简体   繁体   中英

How to call C function in DLL from C#?

I need to call the following function of C by importing DLL in C# but it gives the following error.

I have imported the DLL and successfully executed other functions while this function throws error.

C Method:

long __stdcall VBVMR_Input_GetDeviceDescA(long zindex, long * nType, char * szDeviceName, char * szHardwareId);

C# Code:

[DllImport("VoicemeeterRemote.dll", EntryPoint = "VBVMR_Input_GetDeviceDescA", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
private static extern int VBVMR_Input_GetDeviceDescA(long zindex, ref long nType, [Out] byte[] szDeviceName, [Out] byte[] szHardwareId);

long nType = 0;
byte[] c = new byte[100];
byte[] b = new byte[100];
long i=0;

int rep = VBVMR_Input_GetDeviceDescA(i,ref nType, c, b);

It throws exception on executing VBVMR_Input_GetDeviceDescA as:

A call to PInvoke function 'Voicemeter!Voicemeter.Program::VBVMR_Input_GetDeviceDescA' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

If your exported function is declared with the calling convention __stdcall in the DLL that exports it, you need to import it in your C# code with CallingConvention.StdCall , not Cdecl .

The reason that this calling convention mismatch exhibits an error about "unbalancing the stack" is because after a call to a cdecl function, the calling code is expected to adjust the stack pointer register after the function call to remove the parameters passed to the function from the stack. However, since your function is actually an stdcall function, it does that itself in the ret imm16 instruction it uses, so your stack underflows when the calling code "cleans up the stack" too.

The next problem is that long in C# and long in MSVC are different sizes, so even with the stdcall calling convention, the called function pops the number of bytes corresponding to what it thinks is the correct size for the parameter list, but since C#'s long is not the same size as MSVC's long , the stack is still unbalanced after the ret imm16 instruction at the end of the DLL function. C#'s int type corresponds to a long , however.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM