DG is a god.... wrote:
I have a DLL written in C++ that has the following function exported
from it -:
char** ListHandles(int *processID);
The processID parameter is used to find all associated open file
handles , this value is then written to to return the number of strings
returned in the char**. The return value is an array of strings
listing a set of file handles. I have written a harness in C++ to test
the DLL and it works well in C++...
My task is to now use this DLL in C#.
I have yet to find ANY documentation on how to pass the char ** into a
C# application.
I don't have an example for char** - can you use one for char*** ?
:-)
The following code is not intended for anything else than showing
how to use ReadIntPtr and unsafe.
C++ code:
....
char *p1 = "A";
char *p2 = "BB";
char *p3 = "CCC";
char *p4 = "DDDD";
char *p5 = "EEEEE";
char *p6 = "FFFFFF";
char *pp1[] = { p1, p2, p3 };
char *pp2[] = { p4, p5, p6 };
char **ppp[] = { pp1, pp2 };
PTRPTRPTR_API char ***ptrptrptr(void)
{
return ppp;
}
method #1:
using System;
using System.Runtime.InteropServices;
class MainClass
{
[DllImport("D:\\IDEProjects\\VisualStudio\\PtrPtrPt r\\Release\\PtrPtrPtr.dll")]
private static extern IntPtr ptrptrptr();
public static void Main(string[] args)
{
IntPtr ppp = ptrptrptr();
IntPtr pp1 = Marshal.ReadIntPtr(ppp, 0);
IntPtr pp2 = Marshal.ReadIntPtr(ppp, 4);
IntPtr p1 = Marshal.ReadIntPtr(pp1, 0);
IntPtr p2 = Marshal.ReadIntPtr(pp1, 4);
IntPtr p3 = Marshal.ReadIntPtr(pp1, 8);
IntPtr p4 = Marshal.ReadIntPtr(pp2, 0);
IntPtr p5 = Marshal.ReadIntPtr(pp2, 4);
IntPtr p6 = Marshal.ReadIntPtr(pp2, 8);
string s1 = Marshal.PtrToStringAnsi(p1);
string s2 = Marshal.PtrToStringAnsi(p2);
string s3 = Marshal.PtrToStringAnsi(p3);
string s4 = Marshal.PtrToStringAnsi(p4);
string s5 = Marshal.PtrToStringAnsi(p5);
string s6 = Marshal.PtrToStringAnsi(p6);
Console.WriteLine(s1 + " " + s2 + " " + s3 + " " + s4 + " " +
s5 + " " + s6);
}
}
method #2:
using System;
using System.Runtime.InteropServices;
class MainClass
{
[DllImport("D:\\IDEProjects\\VisualStudio\\PtrPtrPt r\\Release\\PtrPtrPtr.dll")]
private static extern IntPtr ptrptrptr();
public static void Main(string[] args)
{
IntPtr ppp = ptrptrptr();
for(int i = 0; i < 2; i++)
{
IntPtr pp = Marshal.ReadIntPtr(ppp, 4*i);
for(int j = 0; j < 3; j++)
{
IntPtr p = Marshal.ReadIntPtr(pp, 4*j);
string s = Marshal.PtrToStringAnsi(p);
Console.WriteLine(s);
}
}
}
}
method #3:
using System;
using System.Runtime.InteropServices;
class MainClass
{
[DllImport("D:\\IDEProjects\\VisualStudio\\PtrPtrPt r\\Release\\PtrPtrPtr.dll")]
private static extern IntPtr ptrptrptr();
public static void Main(string[] args)
{
IntPtr ppp = ptrptrptr();
for(int i = 0; i < 2; i++)
{
IntPtr pp = Marshal.ReadIntPtr(ppp, 4*i);
for(int j = 0; j < 3; j++)
{
IntPtr p = Marshal.ReadIntPtr(pp, 4*j);
for(int k = 0; k < (3*i+j+1); k++)
{
byte b = Marshal.ReadByte(p, k);
Console.Write((char)b);
}
Console.WriteLine();
}
}
}
}
method #4:
using System;
using System.Runtime.InteropServices;
unsafe class MainClass
{
[DllImport("D:\\IDEProjects\\VisualStudio\\PtrPtrPt r\\Release\\PtrPtrPtr.dll")]
private static extern byte ***ptrptrptr();
public static void Main(string[] args)
{
byte ***ppp = ptrptrptr();
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < (3*i+j+1); k++)
{
Console.Write((char)ppp[i][j][k]);
}
Console.WriteLine();
}
}
}
}
Arne