M
Marek
Hi
I'm trying to call a native C++ dll using the following code (both C# and
C++ code segments included). When I make the call to the method
(AddTwoDoubles) that has no return value all is fine. When I try and call a
function that returns a double (AddTwoDoubles2) I get the following message:
PInvokeStackImbalance was detected
Message: A call to PInvoke function 'tempModule!<Module>::AddTwoDoubles2'
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.
I can't see what I'm doing wrong.
Thanks for any help that anyone can provide.
Marek
=====================================================================
C# code follows.
=====================================================================
//...Set up the return value:
//Type returnType = null; //...Function (AddTwoDoubles) with void return
works
Type returnType = typeof(double); //...Function (AddTwoDoubles2) does not
work
//...Set up the parameters:
Type[] parameterTypes = new Type[2];
object[] parameterValues = new object[2];
parameterTypes[0] = typeof(double);
parameterValues[0] = 2.0;
parameterTypes[1] = typeof(double);
parameterValues[1] = 2.0;
// Create a dynamic assembly and a dynamic module
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "tempDll";
AssemblyBuilder assemblyBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder =
assemblyBuilder.DefineDynamicModule("tempModule");
// Dynamically construct a global PInvoke signature using the input
information
MethodBuilder methodBuilder =
moduleBuilder.DefinePInvokeMethod(entryPointName, dllName,
MethodAttributes.Static | MethodAttributes.Public |
MethodAttributes.PinvokeImpl, CallingConventions.Standard, returnType,
parameterTypes, CallingConvention.Winapi, CharSet.Ansi);
moduleBuilder.CreateGlobalFunctions();
// Get a MethodInfo for the PInvoke method
MethodInfo methodInfo = moduleBuilder.GetMethod(entryPointName);
// Invoke the static method and return whatever it returns
ParameterInfo[] parameterInfo = methodInfo.GetParameters();
try
{
Object returnValue = methodInfo.Invoke(null, parameterValues);
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
=====================================================================
C++ code follows
=====================================================================
extern "C"
{
__declspec( dllexport ) void WINAPI AddTwoDoubles(double a, double b)
{
CString str;
str.Format(_T("%lf + %lf = %lf"), a, b, a+b);
AfxMessageBox(str);
}
__declspec( dllexport ) double WINAPI AddTwoDoubles2(double a, double b)
{
return a+b;
}
}
I'm trying to call a native C++ dll using the following code (both C# and
C++ code segments included). When I make the call to the method
(AddTwoDoubles) that has no return value all is fine. When I try and call a
function that returns a double (AddTwoDoubles2) I get the following message:
PInvokeStackImbalance was detected
Message: A call to PInvoke function 'tempModule!<Module>::AddTwoDoubles2'
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.
I can't see what I'm doing wrong.
Thanks for any help that anyone can provide.
Marek
=====================================================================
C# code follows.
=====================================================================
//...Set up the return value:
//Type returnType = null; //...Function (AddTwoDoubles) with void return
works
Type returnType = typeof(double); //...Function (AddTwoDoubles2) does not
work
//...Set up the parameters:
Type[] parameterTypes = new Type[2];
object[] parameterValues = new object[2];
parameterTypes[0] = typeof(double);
parameterValues[0] = 2.0;
parameterTypes[1] = typeof(double);
parameterValues[1] = 2.0;
// Create a dynamic assembly and a dynamic module
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "tempDll";
AssemblyBuilder assemblyBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder =
assemblyBuilder.DefineDynamicModule("tempModule");
// Dynamically construct a global PInvoke signature using the input
information
MethodBuilder methodBuilder =
moduleBuilder.DefinePInvokeMethod(entryPointName, dllName,
MethodAttributes.Static | MethodAttributes.Public |
MethodAttributes.PinvokeImpl, CallingConventions.Standard, returnType,
parameterTypes, CallingConvention.Winapi, CharSet.Ansi);
moduleBuilder.CreateGlobalFunctions();
// Get a MethodInfo for the PInvoke method
MethodInfo methodInfo = moduleBuilder.GetMethod(entryPointName);
// Invoke the static method and return whatever it returns
ParameterInfo[] parameterInfo = methodInfo.GetParameters();
try
{
Object returnValue = methodInfo.Invoke(null, parameterValues);
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
=====================================================================
C++ code follows
=====================================================================
extern "C"
{
__declspec( dllexport ) void WINAPI AddTwoDoubles(double a, double b)
{
CString str;
str.Format(_T("%lf + %lf = %lf"), a, b, a+b);
AfxMessageBox(str);
}
__declspec( dllexport ) double WINAPI AddTwoDoubles2(double a, double b)
{
return a+b;
}
}