Error calling unmanaged DLL function from managed code

I wrote a DLL in unmanaged visual C ++, and I have a slight problem with making it work with both C # and C ++ applications. Here's what the prototype looks like in the C ++ DLL:

extern "C" __declspec(dllexport) int WINAPI ZBNConnect( UCHAR dev, LPARAM hWnd, ZBCallbackFn rfn, ZBCallbackFn nfn, int DevType, byte * DevAddr, ZBCallbackFn dfn );

My C # application can reference this function without problems, but when it tries to call the function, an exception is thrown:

catch (Exception e) { /* ... */ }

e.Message = "The reference to the object is not installed in the instance of the object."

Oddly enough, if I take it WINAPIout of the prototype into a DLL and recompile, the C # application calls the function without any problems. Unfortunately, it WINAPImust remain, because this is how a function is defined in a C ++ application.

This feature is currently being prototyped in a C # application as follows:

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

#, ? .

EDIT:

([DllImport...]) , , , DLL, . DLL API.

+3
5

, WINAPI DLL. , WINAPI . :

#pragma comment(linker, "/EXPORT:ZBNConnect=_ZBNConnect@28")
0

- . , . , , [DllImport]. , , LoadLibrary GetProcAddress(). [DllImport] . , .

+3

WINAPI .

Try

[UnmanagedFunctionPointer(CallingConvention = CallingConvention.StdCall]
public delegate Int32 ZBNConnectDelegate(Byte dev, IntPtr hWnd, USBCallbackDelegate rfn, NotifyCallbackDelegate nfn, Int32 DevType, Byte[] DevAddr, ZBdebugCallbackDelegate dfn);
0

extern "C" __declspec(dllexport) int WINAPI ZBNConnect( UCHAR dev, LPARAM hWnd, ZBCallbackFn rfn, ZBCallbackFn nfn, int DevType, byte * DevAddr, ZBCallbackFn dfn );

public delegate int ZBNConnectDelegate(uint dev, IntPtr hWnd, USBCallbackDelegate rfn, NotifyCallbackDelegate nfn, uint DevType, byte[] DevAddr, ZBdebugCallbackDelegate dfn);

++ UCHARs (dev) 1- , # uint - 4. , - WINAPI . , P/Invoke DllImport, , , , .

0

If you can find the correct DLL at runtime by C #, I would use two DllImport declarations:

[DllImport("Dll1.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "ZBNConnect")]
extern static int ZBNConnect1(...)
[DllImport("Dll2.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "ZBNConnect")]
extern static int ZBNConnect2(...)

public static int ZBNConnect(...)
{
    if (UseDll1)
        return ZBNConnect1(...);
   return ZBNConnect2(...);
}

Note

P / Invoke is passed by dynamic loading. If you never call ZBNConnect1, Dll1.dll never loads and vice versa.

Update

Added EntryPoint = to DllImport.

0
source

Source: https://habr.com/ru/post/1787032/


All Articles