c++ - Contradictory behavior in C to C# array marshalling -



c++ - Contradictory behavior in C to C# array marshalling -

i have 2 illustration same code. can retrieve info of 1 c# , failed have right info other. here are:

works good

c++ part:

__declspec(dllexport) void** enumeratedevices(int *disize){ array<deviceinfo> diarray; framewoek::enumeratedevices(&diarray); *disize = diarray.getsize(); deviceinfo dp[255]; (int = 0; < diarray.getsize(); i++) dp[i] = diarray[i]; void* p = dp; homecoming &p; }

c# part:

[dllimport("wrapper.dll")] static extern intptr enumeratedevices(out int devicessize); public static deviceinfo[] enumeratedevices() { int devicessize; intptr arraypointer = enumeratedevices(out devicessize); intptr[] array = new intptr[devicessize]; marshal.copy(arraypointer, array, 0, devicessize); deviceinfo[] arrayobjects = new deviceinfo[devicessize]; (int = 0; < devicessize; i++) arrayobjects[i] = new deviceinfo(array[i]); homecoming arrayobjects; }

don't works expected

c++ part:

__declspec(dllexport) void** sensorinfo_getsupportedvideomodes(sensorinfo* si, int *disize){ const array<videomode>& diarray = si->getsupportedvideomodes(); *disize = diarray.getsize(); videomode dp[255]; (int = 0; < diarray.getsize(); i++) dp[i] = diarray[i]; void* p = dp; homecoming &p; }

c# part:

[dllimport("wrapper.dll")] static extern intptr sensorinfo_getsupportedvideomodes(intptr objecthandler, out int arraysize); public videomode[] getsupportedvideomodes() { int arraysize; intptr arraypointer = sensorinfo_getsupportedvideomodes(this.handle, out arraysize); intptr[] array = new intptr[arraysize]; marshal.copy(arraypointer, array, 0, arraysize); videomode[] arrayobjects = new videomode[arraysize]; (int = 0; < arraysize; i++) arrayobjects[i] = new videomode(array[i]); homecoming arrayobjects; }

as can see want pointer of objects. sec illustration give me invalid pointers. don't know why. big library trying create .net wrapper , works except function.

note: array<> template class containing 2 field, size , array , couple of methods.

*edit: know local variable (even vs give me warning), why first 1 works then?!

*edit 2:

i solved sec problem using @jefferythomas answer. , has no problem: c++ side:

__declspec(dllexport) void* sensorinfo_getsupportedvideomodes(sensorinfo* si, int *disize){ const array<videomode>& diarray = si->getsupportedvideomodes(); *disize = diarray.getsize(); videomode** dp = new videomode*[255]; (int = 0; < diarray.getsize(); i++) dp[i] = const_cast<videomode*>(&(diarray[i])); homecoming dp; } __declspec(dllexport) void sensorinfo_destroyvideomodesarray(videomode** dp){ delete[] dp; }

currently have problem changing first function @jefferythomas suggested. let's take code tell u problem. c++ side:

__declspec(dllexport) void** framework_enumeratedevices(int *disize){ array<deviceinfo> diarray; framework::enumeratedevices(&diarray); *disize = diarray.getsize(); deviceinfo* dp = new deviceinfo[255]; (int = 0; < diarray.getsize(); i++) dp[i] = diarray[i]; void** p = new void*; *p = dp; homecoming p; } __declspec(dllexport) void framework_destroydevicesarray(void **p){ deviceinfo *dp = (deviceinfo *)*p; //delete [] dp; delete p; }

c# side:

[dllimport("wrapper.dll")] static extern intptr framework_enumeratedevices(out int devicessize); [dllimport("wrapper.dll")] static extern intptr framework_destroydevicesarray(intptr arraypointer); public static deviceinfo[] enumeratedevices() { int devicessize; intptr arraypointer = framework_enumeratedevices(out devicessize); intptr[] array = new intptr[devicessize]; marshal.copy(arraypointer, array, 0, devicessize); deviceinfo[] arrayobjects = new deviceinfo[devicessize]; (int = 0; < devicessize; i++) arrayobjects[i] = new deviceinfo(array[i]); framework_destroydevicesarray(arraypointer); homecoming arrayobjects; }

and problems:

i cant maintain "delete [] dp" in destroy function. not delete array, delete info well. i can have first pointer (first item of array) correctly. other pointers incorrect. don't know why. tried changing deviceinfo array of pointers instead of array of object straight (like sec function) , still no success.

currently think because of array<> class dispose , destroy everything.

edit 3: found solution first problem my-self. jeff putting me in right direction.

the problem here returning stack variable. bad idea.

both videomode dp[255]; , deviceinfo dp[255]; destroyed when function returns. happens memory has not been overwritten in first case, not lucky in sec case.

in past i've allocated heap , provided sec releasexxxx method free memory up.

__declspec(dllexport) void** enumeratedevices(int *disize){ array<deviceinfo> diarray; framewoek::enumeratedevices(&diarray); *disize = diarray.getsize(); deviceinfo *dp = new deviceinfo[255]; (int = 0; < diarray.getsize(); i++) dp[i] = diarray[i]; void** p = new void*; *p = dp; homecoming p; } __declspec(dllexport) void releaseenumeratedevices(void **p){ deviceinfo *dp = (deviceinfo *)*p; delete [] dp; delete p; }

c#

[dllimport("wrapper.dll")] static extern intptr enumeratedevices(out int devicessize); static extern void releaseenumeratedevices(intptr arraypointer); public static deviceinfo[] enumeratedevices() { int devicessize; intptr arraypointer = enumeratedevices(out devicessize); intptr[] array = new intptr[devicessize]; marshal.copy(arraypointer, array, 0, devicessize); deviceinfo[] arrayobjects = new deviceinfo[devicessize]; (int = 0; < devicessize; i++) arrayobjects[i] = new deviceinfo(array[i]); releaseenumeratedevices(arraypointer); homecoming arrayobjects; }

c# c++ pinvoke marshalling

Comments

Popular posts from this blog

web services - java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.proxy.Enhancer -

Accessing MATLAB's unicode strings from C -

javascript - mongodb won't find my schema method in nested container -