Я написал DLL на неуправляемом Visual C ++, и у меня возникли небольшие проблемы с тем, чтобы заставить его работать как с приложениями C #, так и C ++.Вот как выглядит прототип в C ++ DLL:
extern "C" __declspec(dllexport) int WINAPI ZBNConnect( UCHAR dev, LPARAM hWnd, ZBCallbackFn rfn, ZBCallbackFn nfn, int DevType, byte * DevAddr, ZBCallbackFn dfn );
Мое приложение C # может связываться с функцией, нет проблем, но при попытке вызвать функцию выдается исключение:
catch (Exception e) { /* ... */ }
e.Message = "Ссылка на объект не установлена для экземпляра объекта."
Странно, если я возьму WINAPI
из прототипа в DLL и перекомпилирую, вызовет приложение C #функция без проблем.К сожалению, WINAPI
должен остаться, потому что именно так определяется функция в приложении C ++.
Функция в настоящее время прототипируется в приложении C # следующим образом:
public delegate int ZBNConnectDelegate(uint dev, IntPtr hWnd, USBCallbackDelegate rfn, NotifyCallbackDelegate nfn, uint DevType, byte[] DevAddr, ZBdebugCallbackDelegate dfn);
public ZBNConnectDelegate ZBNConnect;
procName = "ZBNConnect";
fUintPtr = Kernel32.GetProcAddress(dllHandle, procName);
if (fUintPtr == UIntPtr.Zero)
{
throw new ArgumentException(procName);
}
fIntPtr = unchecked((IntPtr)(long)(ulong)fUintPtr);
ZBNConnect = (ZBNConnectDelegate)Marshal.GetDelegateForFunctionPointer(fIntPtr, typeof(ZBNConnectDelegate));
Как можноЯ изменить приложение C #, чтобы это работало?Спасибо.
РЕДАКТИРОВАТЬ: Дополнительная информация
Статическая ссылка ([DllImport...]
) не вариант, потому что в зависимости от того, какое оборудование подключено к системе, различные библиотеки DLL, которыеподдерживает подключенное оборудование загружается во время выполнения.Обе библиотеки DLL имеют одинаковые вызовы API.