Passing a string from a C# program to a C\C++ dll

D

dushkin

Hi all,

I have a 3rd party DLL written in C or C++. I don't have the code and
have no idea about the calling convention.

What I do know, is that the function prototype is:

int func(char *servername, int portnum, int options);

Everything I tried brought me the following message:

-------------------------------------------------

When I tried:


[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string dllName);

[DllImport("kernel32.dll", CharSet=CharSet.Ansi)]
static extern IntPtr GetProcAddress(IntPtr hModule, string
procName);

delegate int FuncDelegate(
string Ip,
int port,
int options);

private static IntPtr userApi;

public void CallFunc(string servername, int portnum, int
options)
{
userApi = LoadLibrary("mydll.dll");

IntPtr procAddress = GetProcAddress(userApi, Func");
FuncDelegate f =
(VtcConnectDelegate)Marshal.GetDelegateForFunctionPointer(procAddress,
typeof(FuncDelegate));

f("localhost", 8888, 1);
}

the development web server crashed and this message appeared:

"Managed Debugging Assistant 'PInvokeStackImbalance' has detected a
problem in 'C:\Program Files\Common Files\microsoft shared\DevServer
\10.0\WebDev.WebServer40.EXE'.
Additional Information: A call to PInvoke function 'App_Code.4avp4bfg!
FuncNs.XXXWrapper+FuncDelegate::Invoke' 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."

-----------------------------------------------------------------

When I tried to use:

[DllImport("mydll.dll", CharSet = CharSet.Ansi)]
public static extern int func(string servername, int portnum,
int options);

and
func("localhost", 8888, 1);

I got the message :

"An unhandled exception of type
'System.ServiceModel.FaultException`1' occurred in mscorlib.dll

Additional information: Unable to load DLL 'mydll.dll': The specified
module could not be found. (Exception from HRESULT: 0x8007007E)"

Many thanks!
 
D

dushkin

By the way, in the second test I did, the following code didn't fail,
so the library seems to be loaded (in spite of the message I got
afterwards):

string mFileName = "mydll.dll";
userApi = LoadLibrary(mFileName);
if (userApi == IntPtr.Zero)
{
throw new ApplicationException("Cannot open "
+ mFileName);
}
 
D

dushkin

  I have a 3rd party DLL written in C or C++. I don't have the code and
have no idea about the calling convention.   [...]

Well, then you have some homework to do.  It is not possible to calla
function in a DLL without knowing the calling convention, or at least
without getting it correct.

If it's not documented, you can try declaring the call using different
calling conventions until it works.  That may be sufficient, though it's
no guarantee you'll actually get exactly the right calling convention
(at least two are very similar, being mostly compatible with each other).

The error message you got really does say it all: check the calling
convention and function signature to make sure you're calling the
function correctly.  Note that while "int" is always 32-bits in C#, in
C/C++ it may or may not be.  (Though, I suspect that the issue really is
just the calling convention, and not an argument type mis-match).

Pete

Well, apparently the solution was adding CallingConvention =
CallingConvention.Cdecl to the DllImport statement.
Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top