我想我已經基本理解了如何編寫回調函數的c#委託,但是這個讓我很困惑。 C++的定義如下:用於C++回調的C#委託
typedef int (__stdcall* Callback)(
long lCode,
long lParamSize,
void* pParam
);
和我的C#的做法是:
unsafe delegate int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam);
雖然這似乎是不正確的,因爲我得到一個PInvokeStackInbalance錯誤,這意味着我委託的定義是錯的。
該函數的其餘參數是字符串或整數,這意味着它們不會導致錯誤,如果我只是傳遞一個IntPtr.Zero而不是委託(這意味着我指向一個非空字符串)現有的回調函數)我得到一個AccessViolation錯誤,這也是有道理的。
我在做什麼錯?
編輯:
完整的C++函數是:
int
__stdcall
_Initialize (
const char* FileName,
Callback cbFunction,
int Code,
const char* Name,
unsigned int Option,
unsigned int Option2
);
我的C#的版本是:
[DllImport("MyDll.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int _Initialize (string FileName, CallbackDelegate cbFunction, int Code, string Name, uint Options, uint Options2);
的功能(用於測試)剛打電話的主程序裏面控制檯應用程序:
static void Main(string[] args)
{
CallbackDelegate del = new CallbackDelegate(onCallback);
Console.Write(_Initialize("SomeFile.dat", del, 1000, "", 0, 4));
Console.Read();
}
其中onCallback
是這樣的:
static int onCallback(int lCode, int lParamSize, IntPtr pParam)
{
return 0;
}
我得到了PInvokeStackInbalance
錯誤在哪裏我叫_Initialize
行,如果我通過IntPtr.Zero
而不是委託,函數的定義修改爲IntPtr
而不是CallbackDelegate
然後我收到一個AccessViolationException
。
'函數的參數的其餘部分是字符串或整數「。不要隱藏信息。 –
你有沒有試過不使用不安全?即:代表int CallbackDelegate(int lCode,int lParamSize,IntPtr pParam); – DougEC
@HansPassant我不是在試圖隱藏信息,我試圖離開我認爲不相關的東西。我將編輯問題並添加信息。 – Valandur