Reputation: 371
So I am trying to use a C library in C# with SWIG on Linux(MonoDevelop). Everything compiles and runs just fine, but when I call the MsgBus_UseString the console-out shows gibberish instead of "HappyHappyJoyJoy".
Here's my Main in C#:
public static void Main (string[] args)
{
SWIGTYPE_p_msgbus msgBusObj = msgbus_client.MsgBus_Create();
ret = msgbus_client.MsgBus_setString(msgBusObj, "HappyHappyJoyJoy");
Console.WriteLine ("Set setString ret = "+ret);
ret = msgbus_client.MsgBus_UseString(msgBusObj);
Console.WriteLine ("UseString ret = "+ret);
}
Here is what the function MsgBus_UseString looks like in the C lib:
static int MsgBus_UseString( msgbus_t * pObj )
{
if ( pObj ){
printf("The String = %s", pObj->TheString);
return Connect(pObj->TheString);
}
}
The MsgBus_setString function in the C lib:
int MsgBus_setString( msgbus_t * pObj, const char * theStringIn )
{
int status = 2; // invalid msgbus_t pointer
if( pObj ) {
pObj->TheString = (char*)theStringIn;
status = 0;
}
printf(fp, "pObj->TheString = %s \n", pObj->TheString);
return status;
}
This is what my SWIG interface looks like:
/* Creates wrappers so that msgbus_client can be used in C# */
%module msgbus_client
%{
#include "msgbus_client.h"
#include "msgbus_var.h"
%}
%inline %{
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef long long int int64_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
typedef long int _time_t;
%}
%include "msgbus_client.h"
%include "msgbus_var.h"
Here's the typedef in the msgbus_client.h file:
typedef struct msgbus msgbus_t;
I've been struggling with this for quite some time. The printf in the MsgBus_setString function returns "HappyHappyJoyJoy" but for some reason this data is lost when calling the MsgBus_UseString function. As you can see I call them right after each other and the "set" function returns 0(no error) while the "use" function returns -1(error). This makes sense since the printf is showing that TheString is a bunch of random/unreadable characters. The msgbus struct is quite large so I'd like to avoid wrapping the entire thing, but I'll do it if there is no other way.
Not sure if it's needed but just in case, here is the create function in the C lib:
msgbus_t * MsgBus_Create()
{
struct msgbus * pObj = NULL;
pObj = (struct msgbus*)calloc(1, sizeof(struct msgbus));
if ( pObj ){
pObj->TheString = NULL;
}
return pObj;
}
In case it wasn't obvious I'm a SWIG newb, but based off the documentation this should work. I'm clearly missing something, but I can't seem to figure out what it is. Any help is greatly appreciated.
Edit: Thanks for the quick reply.
Here is the definition of msgbus struct:
struct msgbus{
int fd;
int run;
pthread_t thread;
//.
//. More Stuff
//.
tlv_buffer_t * pSend;
tlv_buffer_t * pResp;
char * TheString; /*!< The String */
};
The definition of the msgbus struct is in msgbus_client.c and is in the msgbus_client.h with the following typedef:
typedef struct msgbus msgbus_t;
Which was mentioned above. Here is the script that does the SWIGing:
# Begin Swiggin! #
echo "Starting to SWIG! ... "
swig -csharp -outdir msgbus_swig msgbus_client.i
Switches="-c -I/home/includes "\
"-Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -g -Wall -D__linux__ "\
# Build binaries #
g++ $Switches -o "$msgbusBin/msgbus_client_wrap.o" "msgbus_client_wrap.c"
# Generate Shared Lib #
g++ -isystem /home/include \
-isystem /home/another/include \
-D__packed__= -DIMAGE_APPS_PROC -DFEATURE_Q_SINGLE_LINK -DFEATURE_Q_NO_SELF_QPTR \
-DFEATURE_LINUX -DFEATURE_NATIVELINUX -DFEATURE_DSM_DUP_ITEMS -DTARGET_desktop \
-I/home/more/include -Wall -Wundef \
-Wstrict-prototypes -Wno-trigraphs -g -Wall -D__linux__ -fpic -shared \
-L/home/lib \
-Wl,-soname,libmsgbus_client.so -o "libmsgbus_client.so" \
"$msgbusBin/msgbus_client.o" "$msgbusBin/msgbus_var.o" "$msgbusBin/msgbus_client_wrap.o" -lmificommon -lc -lrt -lpthread
echo "SWIG complete!"
So I copied a lot of the g++ calls from a make log so there are switches in there that I don't fully understand. Please let me know if I need to display anything else. Thanks again for all your help.
Upvotes: 0
Views: 491
Reputation: 1564
For your string
issue the problem is that you try to marshal a C# string directly to a char *
. But please note char *
stores a pointer and not the string
itself. What you need to do is to copy the string
. For that you probably also need to allocate/reserve memory.
Upvotes: 1