pass an array of strings from C# to a C++ dll and back again -


i have looked around googleverse , stack overflow , have seen several similar questions none of answers have found have worked me. new member not allowed comment on answers in else's question ask clarification have had resort asking own.

ok trying pass string array c# application c++ dll , grab information in c# application. believe passing c++ can't proper strings dll.

i passing c++ so:

[dllimport("kinectplugins.dll", callingconvention = callingconvention.cdecl)]     private static extern void setgrammardata(string[] strarr, int size);       public void setgrammar(string[] strarr)     {         setgrammardata(strarr, strarr.length);     } 

my c++ code looks this:

#define export_api __declspec(dllexport) #pragma data_seg(".shared")     char** grammardata;     int grammardatalength = 0; #pragma data_seg() #pragma comment(linker, "/section:.shared,rws")  export_api void setgrammardata(char** strarr, int size) {     grammardata = strarr;     grammardatalength = size; }  export_api int getgrammardatalength() {     return grammardatalength; } export_api char** getgrammardata() {     return grammardata; } 

my code grabbing information in other c# application looks this:

[dllimport("kinectplugins.dll")] private static extern intptr getgrammardata(); [dllimport("kinectplugins.dll")] private static extern int getgrammardatalength();  public string[] getgrammar() {     int size = getgrammardatalength();     list<string> list = new list<string>();     intptr ptr = getgrammardata();     intptr strptr;     (int = 0; < size; i++)     {         console.writeline("i = " + i);         strptr = marshal.readintptr(ptr);         list.add(marshal.ptrtostringansi(strptr));         ptr += marshal.sizeof(typeof(intptr));     }     return list.toarray(); } 

in theory should work based on research have seen several other people use same code. in practice, happens pass in:

setgrammar(new string[] { "b", "a" }); 

and comes out other side is:

stringarray[0] =  stringarray[1] = h-▬l☺ 

in case can't view reason or stringarray[1] equal h, -, thick line, l , happy face symbol. not put in.

does have idea going wrong this? have been banging head against problem quite while , use feels missing simple here.

edit: per antijon's suggestion did change setgrammardata make copy of strings still running issue.

new code:

(inside data_seg) wchar_t* grammardata; (end data_seg)  export_api void setgrammardata(wchar_t* strarr, int size) {     delete[] grammardata;     grammardata = new wchar_t[size];     std::memcpy(grammardata, strarr, sizeof(wchar_t) * size);     grammardatalength = size; } export_api wchar_t* getgrammardata() {     return grammardata; } 

now end output:

stringarray[0] = 8 stringarray[1] =  

the c# code has remained same. there else need change missing?

edit2: realized wchar_t char, not string, not sure why thought behaved string. drawing board, need figure out how best copy wchar_t**. not experienced c++ don't think it's possible length of wchar_t* without passing in myself have it.

edit3: got working properly.

here ended with:

(inside data_seg) std::wstring* grammardata; (end data_seg)  export_api void setgrammardata(wchar_t** strarr, int size) {     delete[] grammardata;     grammardatalength = size;     grammardata = new std::wstring[size];     for(int = 0; < size; i++)     {         grammardata[i] = std::wstring(strarr[i]);     } }  export_api const wchar_t** getgrammardata() {     const wchar_t** wct = new const wchar_t*[grammardatalength];     for(int = 0;i<grammardatalength;i++)     {         const wchar_t* t = grammardata[i].c_str();         wct[i] = t;     }     return wct; } 

edit4: thought had working properly, incorrect. testing exe passing when passing through dll exe nothing come through. have working:

(inside data_seg) wchar_t grammardata[32][50] = {}; (end data_seg)  export_api void setgrammardata(wchar_t** strarr, int size) {     grammardatalength = size;     for(int = 0; < size; i++)     {         wcscpy(grammardata[i], strarr[i]);     }     grammardatachanged = 1; }  export_api wchar_t** getgrammardata() {     wchar_t** wct = new wchar_t*[grammardatalength];     for(int = 0;i<grammardatalength;i++)     {         wct[i] = grammardata[i];     }      grammardatachanged = 0;     return wct; } 

couple of possible problems here:

  1. by default, .net marshal wchar_t, not char. need mark input/output string parameters marshalasattribute use char.
  2. if want keep strings, need make copies of them within c function. pointers given in function call setgrammardata not guaranteed persist.

Comments

Popular posts from this blog

java - Jmockit String final length method mocking Issue -

asp.net - Razor Page Hosted on IIS 6 Fails Every Morning -

c++ - wxwidget compiling on windows command prompt -