3

So in my c++.dll file i got the following function:

    DLL void GetUserPass(char* &userName, char* &passWord)
{
    userName = "ceva";
    passWord = "altceva";
}

Now I want to call this from c# but it gives me an error:

[DllImport("myDLL.dll")]
private static extern void GetUserPass(ref string userName, ref string passWord);

static void f()
{
        string userName ="";
        string passWord ="";

        GetUserPass(ref userName, ref passWord);
}

And the error is:

A call to PInvoke function 'Download FTP Archive!Download_FTP_Archive.Program::GetUserPass' 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.

Should I try in C++ dll file something like:

using std::string;
 DLL void GetUserPass(string &userName, string &passWord)
{
    userName = "ceva";
    passWord = "altceva";
}
gideon
  • 19,329
  • 11
  • 72
  • 113
Thanatos
  • 1,176
  • 8
  • 18
  • possible duplicate of [Strings in c++?](http://stackoverflow.com/questions/7666821/strings-in-c) – stijn May 21 '12 at 08:41
  • searching on, for example, "c++ c# string interop" easily gives thousands of hits explaining how to deal with this – stijn May 21 '12 at 08:42
  • Perhaps a link to one of these thousands of hits would be more useful than a comment detailing their existence ¯\_(ツ)_/¯ – BackDoorNoBaby May 03 '16 at 17:04

2 Answers2

3

try the following:

DLL void __stdcall GetUserPass(char* &userName, char* &passWord)
{
    userName = "ceva";
    passWord = "altceva";
}



[DllImport("myDLL.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
private static extern void GetUserPass(ref IntPtr userName, ref IntPtr passWord);
static void f()
{
        IntPtr userNamePtr = new IntPtr();
        IntPtr passWordPtr = new IntPtr();
        GetUserPass(ref userNamePtr, ref passWordPtr);
        string userName = Marshal.PtrToStringAnsi( userNamePtr );
        string passWord = Marshal.PtrToStringAnsi( passWordPtr );
}
smerlin
  • 6,446
  • 3
  • 35
  • 58
0

I am not a c++ developer, but I am a bit familiar with c++ semantics. This char* &userName makes no sense to me. Maybe I am wrong, but try char* userName and see whether it works for you.

Michal B.
  • 5,676
  • 6
  • 42
  • 70
  • no it doesn't work :( char* for me denotes a pointer to a terminated zero char (strings) and the & means to keep the value. I don't know if I remembered ok. – Thanatos May 21 '12 at 08:42
  • 1
    his C++ function is fine, your proposed change would break its semantics. However `char*&` may not be the best type for marshalling – smerlin May 21 '12 at 08:46
  • OK, I see now that it could work. Mixing reference type with a pointer was a bit confusing for me. There is a problem with c++ using ansi strings and c# unicode. Maybe you should specify this in your code? Read about it here: http://stackoverflow.com/questions/683013/interop-sending-string-from-c-sharp-to-c – Michal B. May 21 '12 at 08:56