467,132 Members | 1,226 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

Post your question to a community of 467,132 developers. It's quick & easy.

DefinePInvokeMethod causing PInvokeStackImbalance when returning a value from the native function call

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(asse mblyName,
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;
}
}
Jan 9 '06 #1
  • viewed: 2244
Share:
2 Replies
Not sure where the stack imbalance comes from, but IMO you are missing:

methodBuilder.SetImplementationFlags(MethodImplAtt ributes.PreserveSig);
before you call:
| moduleBuilder.CreateGlobalFunctions();

Willy.

"Marek" <no*****@dnv.com> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl...
| 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(asse mblyName,
| 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;
| }
| }
|
|
Jan 9 '06 #2
Hi Willy

That certainly did the trick. Thank you.

Have you any experience of what changes I need to make to the code to pass
arrays and return values (byref as opposed to byval) as well as the good old
passing and retrieval of string parameters?

Thanks again.

Marek

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:O8**************@TK2MSFTNGP12.phx.gbl...
Not sure where the stack imbalance comes from, but IMO you are missing:
methodBuilder.SetImplementationFlags(MethodImplAtt ributes.PreserveSig);
before you call:
| moduleBuilder.CreateGlobalFunctions();

Willy.

"Marek" <no*****@dnv.com> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl...
| 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(asse mblyName,
| 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;
| }
| }
|
|

Jan 9 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Matthias Klöpper | last post: by
1 post views Thread by Claire | last post: by
15 posts views Thread by Alpha | last post: by
94 posts views Thread by Samuel R. Neff | last post: by
2 posts views Thread by linuxfedora@yahoo.com.hk | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.