Win32Delphiプログラムで.NETランタイムをホストできるようにする独自のglue-layer-code-thingamajigがあります。これにより、時間の経過とともに.NETへの段階的な移行が可能になりました。
しかし、時々問題が発生します。昨日、SOでJclの.NETホストの実装に関する回答を見たので、明らかな違いがあるかどうかを確認したいと思いました。
あることがわかりましたが、それが何をするのか、なぜ、そして私が同じことをする必要があるのかどうかはわかりません。確かに試してみますが、この奇妙なコードの背後にある理由を理解している他の誰かに、それが何をするのかを教えてもらいたいと思います。
やがて、Jcl実装の使用に切り替える可能性がありますが、リリースが差し迫っているため、現在の問題を修正するために絶対に必要でない限り、このレベルのコードでの大規模なオーバーホールは正当化されません。切り替えることをお勧めします。
とにかく、違いは、.NET関数を呼び出して.NETランタイムをロードしてバインドする方法、基本的には.NETdllからエクスポートされた関数を呼び出す方法にあります。
これが私のコードです:
type
TCorBindToRuntimeEx = function(pwszVersion: PWideChar;
pwszBuildFlavor: PWideChar;
startupFlags: DWord; rclsid, riid: PGUID;
out ppv: IUnknown): Integer; stdcall;
...
var
CorBindToRuntimeEx : TCorBindtoRuntimeEx = nil;
...
CorBindToRuntimeEx := GetProcAddress(Runtimehandle, 'CorBindToRuntimeEx');
...
clsid := CLASS_CorRuntimeHost;
iid := IID_ICorRuntimeHost;
rc := CorBindToRuntimeEx('v2.0.50727', 'wks', 0, @clsid,
@iid, UnkRuntimeEngine);
ここで、GetProcAddressを使用して、エクスポートされた関数のアドレスを変数にロードし、stdcall
関数ポインターとして入力してから呼び出します。これはうまくいきます。私が言ったように、いくつかのケースで奇妙なエラーメッセージに関するいくつかの問題。
さて、ここに彼らのコードがあります、そしてアセンブラーコードを持つ関数に特に注意を払ってください。
function CorBindToRuntimeEx(pwszVersion, pwszBuildFlavor: PWideChar;
startupFlags: DWORD; const rclsid: TCLSID; const riid: TIID;
out pv): HRESULT; stdcall;
{$EXTERNALSYM CorBindToRuntimeEx}
...
var
_CorBindToRuntimeEx: Pointer = nil;
function CorBindToRuntimeEx;
begin
GetProcedureAddress(_CorBindToRuntimeEx, mscoree_dll,
'CorBindToRuntimeEx');
asm
mov esp, ebp
pop ebp
jmp [_CorBindToRuntimeEx]
end;
end;
...
OleCheck(CorBindToRuntimeEx(PWideCharOrNil(ClrVer),
PWideChar(ClrHostFlavorNames[Flavor]), Flags,
CLASS_CorRuntimeHost, IID_ICorRuntimeHost,
FDefaultInterface));
ここでSOで水平スクロールバーを回避するためにコードを少し再フォーマットしましたが、いくつかの改行とインデントを追加するだけで、コードはそのままです。
最後の呼び出しはおそらく無関係であり、基本的には同じパラメーターを渡します(オプション値として0を渡すことに注意してください。ただし、Jclコードが使用するのと同じ特定の引数を使用して試しましたが、問題はまだ残っています。現在)。
だから、私の質問は、アセンブラコードは彼**が何をするのかということです。私はそれが技術的な意味で何をするかを知っています、私は以前にアセンブリをプログラミングしていたので、それはスタックポインタを操作します。
問題は、なぜこれを行わなければならないのかということです。わからない。
結局、スタックフレームが完全ではないという stdcall
ことでしょうか?
今日は教えてください。
編集:わかりました、それに応じてコードを変更しましたが、まだ問題が残っているので、そうではありませんでした。結局のところ、サードパーティのコードを掘り下げるWinDbgを実行しているようです。