473,395 Members | 1,558 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

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
2 2488
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Matthias Klöpper | last post by:
Hi, I have a little problem with supplying a mixed set of byVal and byRef parameters to a dynamically created PInvoke method. I have the following message signature which works perfectly when...
10
by: BBFrost | last post by:
We just recently moved one of our major c# apps from VS Net 2002 to VS Net 2003. At first things were looking ok, now problems are starting to appear. So far ... (1) ...
1
by: Claire | last post by:
I've now found out how to approach calling the functions of dynamically loaded dlls. Ive never looked at interop so I don't understand a thing I'm doing but I am trying to adapt someone elses...
15
by: Alpha | last post by:
I was told that Unix API can only be called using C++, ATL and MFC. However, I was also told that C# can do that through Pinvoke to a DLL that interfaces with the Unix API. Can someone direct me...
1
by: Marek | last post by:
Hi I need to call a native function in a C++ dll from my C#. The C++ function declaration is shown below. The C# code that I have been trying to perform the call is also shown below. All it is...
94
by: Samuel R. Neff | last post by:
When is it appropriate to use "volatile" keyword? The docs simply state: " The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock...
2
by: John M. Gamble | last post by:
I'm getting this message in Visual Studio 2005: PInvokeStackImbalance was detected Message: A call to PInvoke function 'Refresh!Refresh.Main::WNetAddConnection2' has unbalanced the stack. ...
2
by: linuxfedora | last post by:
I wrote a class for playing wav file, the code: class SoundPlayer { // flag values for SoundFlags argument on PlaySound public int SND_SYNC = 0x0000; // play synchronously (default) public...
1
by: news.microsoft.com | last post by:
I am getting the following error on the return from a function call.It specically happens on the assignment of the return value from the function call. No error happens inside the function. The...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.