1

I have a third party c dll which I want to use in my c# project. I have managed to import one method which reads the header of a file. Now I want to access the method that reads the data. I think the problem is the struct containing an array of strings so I have tried various things such as a list of StringBuilder, creating a list of strings and passing it as an array, to just creating a string array directly (as shown below). After spending a whole day on this already, I no longer know what to do anymore. I am also not sure if I can just pass a decimal array the way I do now (since it is not listed at http://msdn.microsoft.com/en-us/library/ac7ay120(v=vs.100).aspx).

C header of the dll:

enum id_retrieve_enum {
  GET_ID = 1,
  DO_NOT_GET_ID,  // id is in file
  NO_ID_IN_FILE,
  CREATE_ID       // id is not in file
};

struct id_struct {
  char **values;                     // allocated
  int size;                          // optional: DEFAULT_VALUE = NULL_INT
  enum id_retrieve_enum retrieve;    // optional
};

int importdata(char *fullfilename, int numrows, int numcols, int startrow, 
               decimal *dataset, struct id_struct *ids);

C# code of enum and struct:

public enum id_retrieve_enum
{
  GET_ID = 1,
  DO_NOT_GET_ID,  // id is in file    
  NO_ID_IN_FILE,
  CREATE_ID       // id is not in file
};

[StructLayout(LayoutKind.Sequential)]
public struct id_struct
{
  [MarshalAs(UnmanagedType.SafeArray)]
  public String[] values;
  public int size;
  public id_retrieve_enum retrieve;
};

dllimport:

[DllImport("libpandconv.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int importdata(
  String fullfilename, 
  int numrows, 
  int numcols, 
  int startrow, 
  Decimal[] dataset,
  [In, Out, MarshalAs(UnmanagedType.Struct)] ref id_struct ids);

Init data and call method:

Decimal[] data = new Decimal[numpoints * highdim];

id_struct ids = new id_struct();
  ids.retrieve = (hasid.Equals(1)) ? id_retrieve_enum.GET_ID : id_retrieve_enum.CREATE_ID;
  ids.values = new String[numpoints];

importdata(inputfilename, numpoints, highdim, startrow, data, ref ids);

where inputfilename has already been marshalled and the numpoints, highdim and startrow are already returned by importheader method which I have already imported.

9
  • have you tried to pass a 2d char array instead of a String array? Commented Feb 21, 2012 at 13:47
  • You are going to need to use IntPtr for values and marshal by hand. A C++/CLI layer would be a possible route also. Who allocates this array of strings and how is it expected to be freed? Commented Feb 21, 2012 at 13:51
  • I attempted this to use IntPtr but it did not work at the time. I am going to try that again now, thanks! Commented Feb 21, 2012 at 14:41
  • @Anne Manual marshalling with IntPtr is actually quite straightforward using the Marshal class. You will still need to tackle the issue of allocation. Do you know which party allocates and how to make the deallocation occur on the same heap? Commented Feb 21, 2012 at 15:05
  • @David I have a C++ example which also calls the C methods and here they allocate the memory before calling the method: ids.values = (char**) malloc (numpoints * sizeof(char*)); and they also free the memory at some later point. So I am trying to do the same now by using IntPtr instead of the String[] and using ids.values = Marshal.AllocHGlobal(numpoints). I have never worked with the Marshal class (or dllimport for that matter) so I don't really know what I am doing so am just trying out different things. I also do not know how to make the deallocation occur on the same heap... Commented Feb 21, 2012 at 15:14

1 Answer 1

2

Have you tried using IntPtr instead of an array and resolving it manually?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.