2011-12-28 47 views
7

Tôi có một DLL được biên dịch trong Delphi 2007 và một ví dụ sử dụng nó trong dự án Delphi khác. Đây là một phần của mã:Gọi hàm delphi DLL từ C# Code

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'; 

Và đây là của tôi C# tương tự:

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); 

Vấn đề là tôi đã cố gắng chỉ phương pháp InitModule và nó ném một ngoại lệ: Một cuộc gọi đến chức năng PInvoke 'ProjTest! ProjTest.MyClass :: InitModule' đã không cân bằng chồng. Điều này có thể do chữ ký PInvoke được quản lý không khớp với chữ ký đích không được quản lý. Kiểm tra rằng quy ước và tham số gọi của chữ ký PInvoke khớp với chữ ký không được quản lý đích.

Vui lòng giúp tôi với điều này. Làm thế nào tôi nên mô tả các chức năng DLL trong C#?

Trả lời

11

Bạn không thể gọi tệp DLL đó từ C#. Vấn đề chính là hai cuộc gọi lại of object. Không có cách nào trong C# để phù hợp với điều đó. Bạn sẽ cần phải sửa đổi các DLL hiện có hoặc thêm một bộ chuyển đổi trung gian DLL. Vì nó là viết tắt của bạn DLL chỉ có thể truy cập từ Delphi hoặc C + + Builder.

Nếu bạn có thể sửa đổi DLL thì sửa đổi bạn cần thực hiện là xóa of object. Nếu bạn cần gọi lại để hành động trên một cá thể thì bạn sẽ cần phải chuyển thể hiện dưới dạng tham số. Tuy nhiên, các đại biểu C# có thể bọc tất cả những thứ đó một cách minh bạch để bạn chỉ cần chuyển thể hiện dưới dạng tham số nếu bạn cần DLL có thể truy cập được từ các ngôn ngữ khác, ví dụ: Delphi.

Vấn đề khác là tham số mảng mở. Điều đó cũng không dễ dàng truy cập từ các ngôn ngữ khác. Mặc dù có tricks, tôi khuyên bạn nên chuyển tham chiếu đến phần tử đầu tiên thay vì một mảng mở. Các mảng mở là duy nhất đối với Delphi.

Tôi cũng không hiểu tại sao bạn đang sử dụng loại byte để giữ độ dài mảng. Bạn nên sử dụng Integer cho việc này. Không có gì để đạt được từ việc sử dụng byte và bạn chỉ cần mời tràn. Ngoài ra, MainWindowHandle không được là THandle ở Delphi. Nó phải là HWND.

Đề xuất của tôi với bạn là sửa đổi DLL để có giao diện tương thích với C và do đó có thể truy cập được từ tất cả các ngôn ngữ hỗ trợ. Trong thực tế điều này sẽ làm cho nó có thể truy cập từ tất cả các ngôn ngữ lập trình chính thống.

+0

Tại sao bỏ phiếu xuống? –

Các vấn đề liên quan