Calling c++ DLL from C# Program, unhandled exception - c#

I've done a lot of searching and testing and I've been unable to get this to work correctly.
I'm using MVS Express 2013, compiling a c++ win32 DLL that I hope to call from a c# GUI.
On the C++ Side of things, I have a function that I've exported, and it gets passed a struct. The struct originally contained two strings but it seems easier to pass a char array of known size.
C++ Code:
struct runDetails{
char requestedRuntype[32];
char filename[32];
};
void __declspec(dllexport) WindowRecreatorCall(runDetails* incomingRunRequests);
c# Code:
Attempting to recreate the Struct to pass in:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
public struct runDetails{
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 32)]
public string requestedRuntype;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 32)]
public string filename;
};
Set up the Dynamic DLL Wrapper:
class CallWindowRecreator
{
[DllImport("WindowRecreatorDLL.dll", EntryPoint = "WindowRecreatorCall", CharSet = CharSet.Unicode)]
public static extern void WindowRecreatorCall(ref runDetails runDetails);
};
Actual Call to the DLL:
runDetails testing;
testing.requestedRuntype = "Minimize";
testing.filename = "";
CallWindowRecreator.WindowRecreatorCall(ref testing);
As it is right now, I get this error when I attempt the DLL call:
An unhandled exception of type 'System.BadImageFormatException' occurred in WindowRecreatorGUI.exe
Additional information: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
I've done a lot of googling and code changing and I've learned a lot but I just can't figure this one out. Any tips would be greatly appreciated.
Edit: Changed the code and error recieved
Edit 2: I've changed the C# program from Any CPU to x86 specifically, and now I get this error:
An unhandled exception of type 'System.EntryPointNotFoundException' occurred in WindowRecreatorGUI.exe
Additional information: Unable to find an entry point named 'WindowRecreatorCall' in DLL 'WindowRecreatorDLL.dll'.
And Edit 3 before bed:
I've added an extern c{} around the c++ function. Now I get this error:
Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\Users\Tom\workspace\WindowRecreatorGUI\WindowRecreatorGUI\bin\x86\Debug\WindowRecreatorGUI.vshost.exe'.
Additional information: A call to PInvoke function 'WindowRecreatorGUI!WindowRecreatorGUI.CallWindowRecreator::WindowRecreatorCall' 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.

Your native method takes a pointer to the struct.
In C#, that becomes a ref parameter:
[DllImport("WindowRecreatorDLL.dll", EntryPoint = "WindowRecreatorCall", CharSet = CharSet.Unicode)]
public static extern void WindowRecreatorCall(ref runDetails runDetails);
You also need to pass the correct CallingConvention in the attribute, which is probably Cdecl.

Related

What does 0x8007007F mean when importing a function from an unmanaged DLL?

I'm trying to import functions from an unmanaged DLL into my C# program.
This is my code:
[DllImport("MarkEzd.dll", EntryPoint = "lmc1_Initial2", CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.StdCall)]
public static extern int piplmc1_Initial(string PathName, bool TestMode);
....
int intlmc1_Initial = piplmc1_Initial(m_strEzCADSotwareFullPath, false);
if (intlmc1_Initial > 0)
{
return;
}
The error is, translated from French:
Unable to load DLL MarkEzd.dll, The Specified procedure can not be found Exception de HRESULT : 0x8007007F
What does this error mean?
The error message tells you that the DLL that you loaded does not export a function named lmc1_Initial2.
You should double check the documentation for this library, and maybe it will be obvious where the error is. Perhaps a different DLL exports that function. Perhaps the name has been transcribed incorrectly. Note that letter case matters, so you must get all upper and lower case letters correct.
If the documentation does not help, use a tool like dumpbin or Dependency Walker to inspect the exported function names of the DLL.

P/invoke DLL functions from C++ dll in C#

I have a problem with invoking a few functions from DLL (SDK of some camera). In source of .dll, there is function:
NET_SDK_API LONG CALL_METHOD NET_SDK_Login(char *sDVRIP,WORD wDVRPort,char *sUserName,char *sPassword,LPNET_SDK_DEVICEINFO lpDeviceInfo);
and I am trying to call it from .Net console app with following code:
[STAThread]
static void Main(string[] args)
{
long userid = 0;
_net_sdk_deviceinfo dinfo = new _net_sdk_deviceinfo();
short port = 6036;
try
{
if (DVR.NET_SDK_Init())
{
Console.WriteLine("ok");
userid = DVR.NET_SDK_Login("192.168.1.132", port, "admin", "123456", out dinfo);
userid.ToString();
}
else
{
Console.WriteLine("err");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadKey();
}
i get following error:
A call to PInvoke function 'DVRtest!DVRtest.DVR::NET_SDK_Login' 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.
Init passes fine but i cant get anything else. I tried dozen of solutions and I'm getting nowhere.
Here is source of dll and source of my .Net app. Thanks!
[edit]
As #david pointed out, CallingConvention was wrong and now, i get following error:
The runtime has encountered a fatal error. The address of the error
was at 0x6fda02c7, on thread 0x2554. The error code is 0xc0000005.
This error may be a bug in the CLR or in the unsafe or non-verifiable
portions of user code. Common sources of this bug include user
marshaling errors for COM-interop or PInvoke, which may corrupt the
stack.
Is this error from DLL or CLR (.Net)? I never imported any functions from DLL to .Net, so any help is appreciated.
From the unmanaged source:
#define CALL_METHOD __stdcall
And from the managed source:
[DllImport("DVR_NET_SDK.dll", CallingConvention = CallingConvention.Cdecl)]
Your calling conventions do not match.
As for the edit to the question, that is presumably because the C# struct definition does not match the unmanaged struct. You have failed to translate any of the arrays correctly. They will require the use of [MarshalAs(UnmanagedType.ByValArray, SizeConst=...)].

A call to PInvoke function xxx has unbalanced the stack

I am using C DLL in C# code (.net 4.0) in a console application and facing issue.
When I call the C method it raises the below exception.
"A call to PInvoke function 'ProcessFilesC' 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."
Here is the C code
int ProcessFilesC(
char **p_FilesOrDirs,
ImageInfoC **p_vecImageInfo,
int ***p_vecStackIndexes,
RectC ***p_vecFaces
);
Here is my C# code
[DllImport(#"..\ref\myCApp.dll", CallingConvention = CallingConvention.StdCall)]
unsafe private static extern UInt16 ProcessFilesC(
String[] p_FilesOrDirs,
ref ImageInfoC[] p_vecImageInfo,
out Int32[] p_vecStackIndexes,
out RectC[] p_vecFaces
);
public unsafe struct ImageInfoC
{
public String resizedFilePath; //char* (in C)
public Byte isUsable; //unsigned char (in C)
public UInt32 imageId; //long int in (in C)
public UInt16 stackIndex; //int (in C)
public Boolean isBestPhoto; //unsigned char (in C)
}
Below is C# code to call the method
unsafe
{
iResult = ProcessFilesC(
p_FilesOrDirs, // Value getting passed to DLL
ref p_vecImageInfo,
out p_vecStackIndexes,
out p_vecFaces
);
Console.WriteLine("ProcessFilesC Complete");
}
When code reaches here, I can see that method is processing as it prints in console but after processing, it raises the mentioned exception.
I guess this is due to C DLL is trying to write values in output/ref parameters.
I am not getting where is the issue or what's the wrong in my code.
Please note that I have already uncheck option "Suppress JIT optimization on module load" at Tools -> Options -> Debugging -> General
Please help as soon as poosible.
Thanks for spending to valuable time to read this post.
Thanks,
Kiran
The first thing to check is the calling convention. In most cases the calling convention specified in your DllImport attribute differs from the actual calling convention in the native DLL.

WPF: A call to PInvoke function has unbalanced the stack

I'm encountering this error while using one of method in my .dll reference.
When I call MyRef.SetDbaseId method I'm returned to VS with this error. I've tried to add CallingConvention enum parameters, but all of them does not work for me. I've also opened dll in DependencyWalker to check entry point and param (ulong), which fits in my app. It's confusing because other methods works fine. Any ideas how to solve this problem?
[DllImport("my.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?setdbaseid##YGHK#Z")]
public static extern int SetDbaseID(ulong dbase_id);
ulong tmid = ulong.Parse(p_6);
i = MyRef.SetDbaseID(tmid);
The mangled name, ?setdbaseid##YGHK#Z, demangles to:
int __stdcall setdbaseid(unsigned long);
Which makes your declaration wrong, an unsigned long in native code is 32-bits. And the calling convention is wrong. Fix:
[DllImport("my.dll", EntryPoint = "?setdbaseid##YGHK#Z"))]
public static extern int SetDbaseID(uint dbase_id);

pinvoke to clutter function

I'm trying to pinvoke to a clutter function.
The function is defined in the docs as
ClutterActor * clutter_texture_new_from_file (const gchar *filename, GError **error);
The code I have is as follows:
[DllImport ("libclutter-glx-1.0.so.0")]
private static extern IntPtr clutter_texture_new_from_file (string filename, IntPtr errorData);
And I call it like this:
IntPtr texture = clutter_texture_new_from_file("myImage.jpeg",IntPtr.Zero);
however when called like this in monodevelop on ubuntu I get the following error.
Unix Transport Error
Eventally I would like to get the error reporting working so I can get the gerror result however firstly I need to get past the Unix Transport Error.
The errorData parameter should be marked as "ref IntPtr", although I don't think that should be causing this error since that parameter should be allowed to be NULL. Otherwise, try running this outside Monodevelop. This kind of error may be the result of a segfault elsewhere in your program.

Categories