Hi everyone,
i'm trying to call a DLL written in C from a program C# and got an error at the execution.
Here is the content of my C DLL :
/* file test.h */
#define DLL_EXPORT __declspec(dllexport)
DLL_EXPORT struct struct_test{
int a;
int b;
};
DLL_EXPORT int func_test(struct struct_test * t);
/*********************************************/
/* file test.c */
#include "test.h"
DLL_EXPORT int func_test(struct struct_test * t)
{
return t->a+t->b;
}
and here is my C# code :
using System;
using System.Runtime.InteropServices;
public class csharp_test_class
{
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct struct_test{
public int a;
public int b;
};
[DllImport("test")]
public extern static int func_test(
ref struct_test t
);
public static void Main()
{
struct_test t = new struct_test();
t.a = 3;
t.b = 4;
Console.WriteLine(func_test(ref t));
}
}
The error recevied is :
PInvokeStackImbalance was detected :
A call to PInvoke function 'Project1!csharp_test_class::func_test' 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.
Does someone has an idea how to resolve that problem ?
Thanks in advance for your answers,
Best regards,
Yan302
Loading
YanPosted Jul 19, 2010, 10:13 AM
I found the problem. I have to specify "CallingConvention=CallingConvention.Cdecl" in the DllImport clause.
Best regards,
Sam HobbsPosted Jul 16, 2010, 8:39 PM
First note that the default packing for C++ is not 1; I think it is 8. In your C# definition of csharp_test_class you have "[StructLayout(LayoutKind.Sequential, Pack=1)]" and that will likely be incompatible with the default packing for C++. You need to ensure that the packing is the same for both C++ and C#.
Are you sure that the ref keyword is all that you need for specifying that a parameter is passed to C++ using a C++ style pointer? I am not sure but I think not. If the size of the data being passed is small and if the data being passed is not modified, then it would be easier to pass the data without using the pointer.
You could use the debugger and put a breakpoint in the C++ code in the func_test function and look at the data that is being passed. You could use the memory window to look at the actual contents of memory and that might help.