I have a regular dll with the following function exported.
extern "C" __declspec(dllexport) int FindNeare开发者_JAVA百科stStuff(double _latitude, double _longitude , LocationStruct * locations[])
LocationStruct is very simple
struct LocationStruct
{
long positionIndex;
long item;
};
I'm tryign to call it from c# using
[DllImport("myclever.dll", CharSet = CharSet.None)]
private static extern int FindNearestStuff(double _latitude, double _longitude,
ref LocationStruct [] locations);
It's all cool and funky and I can step into the dll function from the debugger. Inside the dll the LocationStruct array is populated correctly and all is very good.
The problem I have is when it returns back from the dll, the LocationStruct array is not coming back with the data - just empty values...
What am I missing?
thanks so much for your help - you certainly put me onthe right direction and i really appreciate your assistance!
This is the solution which seems to work for me;
[DllImport("myclever.dll", CharSet = CharSet.None)]
private static extern int FindNearestStuff(double _latitude, double _longitude, IntPtr locations);
public static int FindNearestStuff(double _latitude, double _longitude, LocationStruct[] locations)
{
int returnValue = -1;
LocationStruct temp;
temp.roadIndex = 1;
temp.tdist = 1;
int iStructSize = Marshal.SizeOf(temp);
try
{
IntPtr locationsPtr = IntPtr.Zero;
IntPtr buffer = Marshal.AllocHGlobal(iStructSize * 10);
FindNearestRoads(_latitude, _longitude, buffer);
for (int i = 0; i < 10; i++)
{
IntPtr ptr = new IntPtr(buffer.ToInt32() + iStructSize * i);
locations[i] = (LocationStruct)Marshal.PtrToStructure(ptr, typeof(LocationStruct));
}
returnValue = 0;
}
catch
{
}
return returnValue;
}
I'm not sure that you will be able to do this automatically since C# has no way of knowing how many items are returned in the locations variable (I'm assuming that the return value of FindNearestStuff is the number of entries in locations.)
You will have to manually marshal your data using the Marshall class and a process like this:
[DllImport("myclever.dll", CharSet = CharSet.None)]
private static extern int FindNearestStuff(double _latitude, double _longitude,
out IntPtr locations);
public static LocationStruct[] FindNearestStuff(double latitude, double longitude) {
IntPtr locationsPtr = IntPtr.Zero;
int numLocations = FindNearestStuff(latitude, longitude, out locationsPtr);
LocationsStruct[] locations = new LocationsStruct[numLocations];
for (int i = 0; i < numLocations; i++) {
// locationsPtr is a pointer to the struct, so read the value
// at locationPtr which will be the address of the struct and
// then manually marshal the struct from that address
locaitonsStruct[i] = (LocationStruct)Marshal.PtrToStructure(
Marshal.ReadIntPtr(locationsPtr), typeof(LocationsStruct));
// Move to the location pointer to the next address of a
// pointer to a struct
locationsPtr += IntPtr.Size;
}
return locations;
}
I haven't actually tried this so caveat emptor.
精彩评论