Tôi nghĩ rằng về cơ bản tôi đã hiểu cách viết C# đại biểu cho các cuộc gọi lại, nhưng điều này làm tôi bối rối. Các C++ định nghĩa như sau:C# ủy nhiệm cho gọi lại C++
typedef int (__stdcall* Callback)(
long lCode,
long lParamSize,
void* pParam
);
và C# cách tiếp cận của tôi sẽ là:
unsafe delegate int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam);
Mặc dù điều này có vẻ là không chính xác, bởi vì tôi nhận được một lỗi PInvokeStackInbalance, có nghĩa là định nghĩa của tôi về các đại biểu là sai.
Phần còn lại của tham số của hàm là chuỗi hoặc int, có nghĩa là chúng không thể gây ra lỗi, và nếu tôi chỉ chuyển IntPtr.Zero thay cho đại biểu (có nghĩa là tôi trỏ đến một không) chức năng gọi lại tồn tại) Tôi nhận được lỗi AccessViolation, điều này có ý nghĩa tốt.
Tôi đang làm gì sai?
EDIT:
Các đầy đủ C++ chức năng là:
int
__stdcall
_Initialize (
const char* FileName,
Callback cbFunction,
int Code,
const char* Name,
unsigned int Option,
unsigned int Option2
);
C# phiên bản của tôi là:
[DllImport("MyDll.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int _Initialize (string FileName, CallbackDelegate cbFunction, int Code, string Name, uint Options, uint Options2);
Chức năng này (để thử nghiệm) vừa gọi bên trong thói quen chính của ứng dụng bảng điều khiển:
static void Main(string[] args)
{
CallbackDelegate del = new CallbackDelegate(onCallback);
Console.Write(_Initialize("SomeFile.dat", del, 1000, "", 0, 4));
Console.Read();
}
nơi onCallback
là thế này:
static int onCallback(int lCode, int lParamSize, IntPtr pParam)
{
return 0;
}
tôi nhận được lỗi PInvokeStackInbalance
trên đường, nơi tôi gọi _Initialize
, nếu tôi vượt qua một IntPtr.Zero
thay vì các đại biểu, và thay đổi định nghĩa của hàm để IntPtr
thay vì CallbackDelegate
sau đó Tôi nhận được AccessViolationException
.
'Phần còn lại của các thông số của hàm là chuỗi hoặc ints'. Không ẩn thông tin. –
Bạn đã thử sử dụng không an toàn chưa? tức là: delegate int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam); – DougEC
@ HansPassant Tôi không cố che giấu thông tin, tôi đã cố gắng loại bỏ những thứ mà tôi cho là không liên quan. Tôi sẽ chỉnh sửa câu hỏi và thêm thông tin. – Valandur