I've been mixing C# GUI with a C++ code for socket connection handling. The problem is that passing a string to a C++ char* DLL causes it to change its value in the C++ class(?).
I've got a class for handling sockets which was a bit changed to look around for a cause of error and some functions letting me get to the class itself:
extern "C" { __declspec(dllexport)
class mySock
{
int port;
SOCKET littleSock;
public:
char* ipAddress;
mySock() {};
mySock(char* inIP, int inPort);
~mySock();
int initialize();
int sendMsg(char* Msg);
//int addition(int a, int b);
};
}
extern "C" { __declspec(dllexport) mySock* mySock_Create(char* IP, int prt);}
extern "C" { __declspec(dllexport) mySock* mySock_Create1(); }
extern "C" { __declspec(dllexport) int mySock_initialize(mySock* inSocket); }
extern "C" { __declspec(dllexport) int mySock_sendMsg(mySock* inSocket,char* Msg); }
extern "C" { __declspec(dllexport) void mySock_delete(mySock* inSocket); }
extern "C" { __declspec(dllexport) void CopyStr(char* str1, mySock* inSocket)
{
strcpy_s(str1, strlen(str1), inSocket->ipAddress);
};
}
The problem occurs somewhere in usage of mySock_Create.
Basically it is:
mySock* mySock_Create(char* IP, int prt)
{
return new mySock(IP, prt);
}
calling a constructor:
mySock::mySock(char* inIP, int inPort)
{
ipAddress = inIP;
port = inPort;
}
Later ipAddress
is used with inet_addr and connects to the remote server.
Anyway, the code above doesn't allow me to connect to server, but if I simply hardcode the IP address like this:
mySock* mySock_Create(char* IP, int prt)
{
return new mySock("192.168.1.164", prt);
}
It works fine and connects to the local server.
So for checking I added CopyStr which you could see in DLL header code above, and it is supposed to get the IP address of mySock object and write it to C# textbox.
In case of a hardcoded IP address indeed it shows that IP address, but in case of passing an IP address from C# it returns only a not filled rectangle sign which I'm not even able to paste here.
Here's C# code for linking and using the DLL:
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr mySock_Create(StringBuilder IP, int prt);
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int mySock_initialize(IntPtr value);
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int mySock_sendMsg(IntPtr value, string Msg);
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void mySock_delete(IntPtr value);
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr mySock_Create1();
[DllImport("G:\\socketstraning\\klikacz\\MyFirstDLLyay\\Debug\\MyFirstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void CopyStr(StringBuilder str1, IntPtr value);
private void button3_Click(object sender, EventArgs e)
{
StringBuilder str = new StringBuilder("192.168.1.164", 50);
IntPtr we = mySock_Create(str, 16999);
StringBuilder str2 = new StringBuilder("255.255.255.255", 25);
CopyStr(str2, we);
textBox1.Text = str2.ToString();
if (mySock_initialize(we) == -2)
button3.Text = "Ups";
mySock_delete(we);
}
I've also tried using string instead of StringBuilder or adding CharSet=CharSet.Ansi in import options.
I've read quite a bunch of questions and solutions to passing string to char*
in such cases, but I can't work out why value of ipAddress
isn't passed correctly or changes somewhere else.
Hope I stated problem clearly enough as I'm already pretty much out-of-logic after fighting with above code.