C# prototype of C: structure includes void**

G

Guest

I want to access a function implemented in a C-dll with the following
prototype:
getDatabase(CALL_GDS *mStruct)
typedef struct _CALL_GDS {
int ModuleId;
int CPUid;
int argc;
char **argv;//*argv[]
} CALL_GDS;

Now:
1. How would the CALL_GDS (and "char** argv") part look like in the
corresponding
C# prototype?
2. How do I call this C# method ?

Any idea?


C#:

[ StructLayout( LayoutKind.Sequential )]
public struct CALL_GDS
{
public int ModuleId;
public int CPUid;
public int argc;
[MarshalAs(UnmanagedType.ByValArray)]
public IntPtr argv;// pptr //*argv[]
}
 
N

Nicholas Paldino [.NET/C# MVP]

Yosi,

In C#, you would declare CALL_GDS like this:

[StructLayout(LayoutKind.Sequential)]
public struct CALL_GDS
{
public int ModuleId;
public int CPUid;
public int argc;
public IntPtr argv;
}

You would then declare getDatabase as so:

[DllImport("some.dll")]
public static extern void getDatabase(ref CALL_GDS mStruct);

To get the last array, you will have to handle the marshalling yourself.
You will want to do something like this (after you make the call):

// The structure.
CALL_GDS callGds = new CALL_GDS();

// Make the call.
getDatabase(ref callGds);

// The pointer to the string.
IntPtr stringPointer = IntPtr.Zero;

// The array of items in argc. Preallocate.
string[] argv = new string[callGds.argc];

// Cycle through the number of arguments.
for (int index = 0; index < callGds.argc; ++index)
{
// Get the IntPtr corresponding to the index position.
stringPointer = new IntPtr(callGds.argV.ToInt64() + (index *
IntPtr.Size));

// Marshal the string.
argv[index] = Marshal.PtrToStringAnsi(stringPointer);
}

Hope this helps.
 
G

Guest

Great thank you ! It is very helpfull.

the following didn't work will . this return garbage:
stringPointer = new IntPtr(callGds.argV.ToInt64() +...
I change it to :
stringPointer = new IntPtr(Marshal.ReadIntPtr(callGds.argV).ToInt64() +...
now I get the string .
Thanks again, you help me so much I was trying to solve that for more than 3
days.
Yosi.

Nicholas Paldino said:
Yosi,

In C#, you would declare CALL_GDS like this:

[StructLayout(LayoutKind.Sequential)]
public struct CALL_GDS
{
public int ModuleId;
public int CPUid;
public int argc;
public IntPtr argv;
}

You would then declare getDatabase as so:

[DllImport("some.dll")]
public static extern void getDatabase(ref CALL_GDS mStruct);

To get the last array, you will have to handle the marshalling yourself.
You will want to do something like this (after you make the call):

// The structure.
CALL_GDS callGds = new CALL_GDS();

// Make the call.
getDatabase(ref callGds);

// The pointer to the string.
IntPtr stringPointer = IntPtr.Zero;

// The array of items in argc. Preallocate.
string[] argv = new string[callGds.argc];

// Cycle through the number of arguments.
for (int index = 0; index < callGds.argc; ++index)
{
// Get the IntPtr corresponding to the index position.
stringPointer = new IntPtr(callGds.argV.ToInt64() + (index *
IntPtr.Size));

// Marshal the string.
argv[index] = Marshal.PtrToStringAnsi(stringPointer);
}

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I want to access a function implemented in a C-dll with the following
prototype:
getDatabase(CALL_GDS *mStruct)
typedef struct _CALL_GDS {
int ModuleId;
int CPUid;
int argc;
char **argv;//*argv[]
} CALL_GDS;

Now:
1. How would the CALL_GDS (and "char** argv") part look like in the
corresponding
C# prototype?
2. How do I call this C# method ?

Any idea?


C#:

[ StructLayout( LayoutKind.Sequential )]
public struct CALL_GDS
{
public int ModuleId;
public int CPUid;
public int argc;
[MarshalAs(UnmanagedType.ByValArray)]
public IntPtr argv;// pptr //*argv[]
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top