2011-12-28 49 views
7

私はDelphi 2007でコンパイルされたDLLと、他のDelphiプロジェクトで使用しているDLLを持っています。ここでは、コードの一部です:C#コードからdelphi DLL関数を呼び出す

TErrorCallback = function(Msg:PChar):byte of object; 
TSaveEventCallback = function (Line:PChar; HiCode:PChar; LoCode:PChar; MobileNo:PChar):byte of object; 

function InitModule(ErrorCallback:TErrorCallback; SaveEventCallback :TSaveEventCallback; MainWindowHandle:THandle; Sock_Event:integer):byte; stdcall; external 'My.dll' name 'InitModule'; 

function DLLSocketEvent(var msg: TMessage): byte; stdcall; external 'My.dll' name 'DLLSocketEvent'; 

function InitObjList(Objs: array of PChar; NumObjs: byte; Name: PChar):byte; stdcall; external 'My.dll' name 'InitObjList'; 

そしてここでは、私のC#のアナログである:

class Message 
{ 
    unsigned int msg; 
    int wParam; 
    int lParam; 
    int result; 
}; 
delegate byte ErrorCallbackDelegate(string msg); 
delegate byte SaveEventCallbackDelegate(string line, string hiCode, string loCode, string mobileNo); 

[DllImport("My.dll")] 
static extern byte InitModule(ErrorCallbackDelegate errorCallback, SaveEventCallbackDelegate saveEventCallback, IntPtr mainWindowsHandle, Int32 sockEvent); 

[DllImport("My.dll")] 
static extern byte DllSocketEvent(Message msg); 

[DllImport("My.dll")] 
static extern byte InitObjList(string[] objs, byte numObjs, string name); 

ポイントは私だけInitModule方法を試してみたされ、それは例外をthrowed: コールのPInvoke関数に'ProjTest!ProjTest.MyClass :: InitModule'はスタックのアンバランスを起こしました。これは、管理対象のPInvokeシグネチャがアンマネージ対象シグネチャと一致しないためです。 PInvokeシグネチャの呼び出し規約とパラメータが、対象となる管理されていないシグネチャと一致することを確認します。

お願いします。これらのDLL関数をC#でどのように記述すればよいですか?

答えて

11

C#からそのDLLを呼び出すことはできません。主な問題は、2つのof objectコールバックです。 C#でそれに合う方法はありません。既存のDLLを変更するか、中間アダプタDLLを追加する必要があります。 DLLは、DelphiまたはC++ Builderからのみアクセスできます。

DLLを変更できる場合は、of objectを削除する必要があります。インスタンスに対してコールバックが必要な場合は、そのインスタンスをパラメータとして渡す必要があります。しかし、C#デリゲートはすべてを透過的にラップすることができるので、他の言語からアクセスできるようにDLLを必要とする場合は、インスタンスをパラメータとして渡すだけで済みます。デルファイ

その他の問題は、オープンアレイのパラメータです。他の言語からも簡単にアクセスすることはできません。 tricksがありますが、公開配列ではなく最初の要素への参照を渡すことをお勧めします。開いている配列はDelphiに固有です。

byteタイプを使用してアレイの長さを保持する理由もわかりません。これにはIntegerを使用する必要があります。バイトを使用することから得られるものは何もなく、オーバーフローを招待するだけです。また、MainWindowHandleは、デルファイではTHandleであってはなりません。それはHWNDでなければなりません。

私は、DLLを修正してC互換インタフェースを作成し、それをサポートするすべての言語からアクセスできるようにすることをお勧めします。実際には、これはすべてのメインストリームプログラミング言語からアクセス可能になります。

+0

なぜ賛成投票ですか? –

関連する問題