У меня есть DLL, из которой мне нужно P / Invoke следующий метод C:
int DAOpen(HANDLE *hOpen, UNIT *flags, void *callback, void *userData)
Используя P / Invoke Assistant, я создал следующую подпись:
[DllImportAttribute("<libName>", EntryPoint="DAOpen")]
static extern int DAOpen(
out IntPtr hOpen,
ref uint flags,
IntPtr callback,
IntPtr userData);
Параметр callback должен соответствовать следующей сигнатуре C:
void CallBack(
int event,
int socket,
struct _iComStructure *plcom,
void *eventData,
void *myData)
, что переводится как
delegate void CallBack(
int @event,
int socket,
IntPtr plcom,
IntPtr eventData,
IntPtr myData);
Теперь я делаю вызов следующим образом:
void MyCallBack(int @event, int socket, IntPtr plcom, IntPtr eventData, IntPtr myData)
{
// does nothing for now
}
IntPtr hOpen;
uint flags = 0;
CallBack callBack = MyCallBack;
StringBuilder userData = new StringBuilder(userData.ToString());
int rc = DAOpen(
out hOpen,
ref flags,
Marshal.GetFunctionPointerForDelegate(callBack), Marshal.StringToHGlobalAnsi(userData.ToString()));
Проблема с этим кодом заключается в том, что он либо дает сбой, либо мне выдается FatalExecutionEngineError
, когда я выполняю вызов в DAOpen. Я знаю, что это должно быть ошибкой, но я не могу понять ...
Спасибо за вашу помощь!
UPDATE
Как и было предложено, я попытался закрепить обратный вызов следующим образом:
GCHandle callbackHandle = GCHandle.Alloc(callBack, GCHandleType.Pinned);
Я получаю ArgumentException
с этим сообщением:
Object contains non-primitive or non-blittable data
Кажется, это работает нормально, если я не укажу GCHandleType (т.е. я получаю дескриптор), но, конечно, оригинальная проблема остается.
Есть ли причина, по которой я не могу прикрепить делегата?
Спасибо за ваш вклад!