How to read char** from c++ .dll to string in c#

BananaLin 41 Reputation points
2021-09-22T16:21:50.473+00:00

I have a DLL file and need to call functions from the file. From the .h file can see the content as follows:

struct CContourManager_Dll  
{  
	char** m_strOrganNameList;  
	int m_nOrganNameListSize;  
	void* m_pContourManager;  
  
	CContourManager_Dll() :  
		m_strOrganNameList(nullptr),   
		m_nOrganNameListSize(0),  
		m_pContourManager(nullptr)  
	{}  
  
};  

I also wrote the CLASS receiving variable, the content is as follows:

    public unsafe struct CContourManager_Dll  
    {  
        public char** m_strOrganNameList;  
        public int m_nOrganNameListSize;  
        public void *m_pContourManager;  
  
        public CContourManager_Dll(char** stringName, int stringNameLength, void *ID)  
        {  
            m_strOrganNameList = stringName;  
            m_nOrganNameListSize = stringNameLength;  
            m_pContourManager = ID;  
        }  
    }  

In order to test whether the content can be read, I have modified the variable of CLASS, and the content is as follows:

    public unsafe struct CContourManager_Dll  
    {  
        public IntPtr m_strOrganNameList;  
        public int m_nOrganNameListSize;  
        public void *m_pContourManager;  
  
        public CContourManager_Dll(IntPtr stringName, int stringNameLength, void *ID)  
        {  
            m_strOrganNameList = stringName;  
            m_nOrganNameListSize = stringNameLength;  
            m_pContourManager = ID;  
        }  
    }  

I know that char** will be an array after reading, so using the previously used method of reading short arrays, it can indeed read the value, but I don’t know how to convert it into text, and I have tried several variables and will produce errors.

[DllImport(dllroute, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]  
static extern IntPtr OpenContourToContourManager(string strSrcImageFilePath);  
  
  
static unsafe void Main(string[] args)  
{  
  
    string CTRfile = @"D:\1161_1450.ctr";  
  
    IntPtr getTest = OpenContourToContourManager(CTRfile);  
    CContourManager_Dll getTestStructure = (CContourManager_Dll)Marshal.PtrToStructure(getTest, typeof(CContourManager_Dll));  
  
    //******************************************************************************  
    CContourManager_Dll gget = (CContourManager_Dll)Marshal.PtrToStructure(getTest, typeof(CContourManager_Dll));  
  
    IntPtr result_s = getTestStructure.m_strOrganNameList;  
    int short_size = sizeof(short);  
    int p_s_cursor = 0;  
    Array pshImageData = Array.CreateInstance(typeof(short), getTestStructure.m_nOrganNameListSize);  
    for (int i = 0; i < getTestStructure.m_nOrganNameListSize; i++)  
    {  
  
        short data = (short)Marshal.PtrToStringAnsi(getTestStructure.m_strOrganNameList + p_s_cursor, typeof(short));  
        pshImageData.SetValue(data, i);  
        p_s_cursor += short_size;  
  
    }  
  
    string detail_string_HW = String.Format("Height: {0}", getTestStructure.m_nOrganNameListSize);  
    string[] yoyo = new string[getTestStructure.m_nOrganNameListSize];  
    Console.WriteLine(detail_string_HW);  
  
    for (int i = 0; i < getTestStructure.m_nOrganNameListSize; i++)  
    {  
  
  
        // detail_string_data += pshImageData.GetValue(i, j) + " ";  
        Console.WriteLine(pshImageData.GetValue(i));  
        yoyo[i] = Convert.ToString(pshImageData.GetValue(i));  
  
  
        Console.WriteLine();  
  
    }  
    //******************************************************************************  
  
}  

Using the above method, the content read looks like a pointer, I hope the value readout can become a string, what should I do?
Hope someone can help me and give me advice, Thanks.

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,110 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,786 questions
0 comments No comments
{count} votes

Accepted answer
  1. RLWA32 45,941 Reputation points
    2021-09-22T22:11:14.893+00:00

    One way to marshal the unmanaged char* (C-style) strings from the char** array -

    IntPtr ptr;   // Contains the char** pointer to narrow string array 
    int nEntries; // The number of narrow strings in the array
    
    IntPtr[] ptrArray = new IntPtr[nEntries]; 
    Marshal.Copy(ptr, ptrArray, 0, nEntries); 
    foreach(IntPtr i in ptrArray)
    {
        string s = Marshal.PtrToStringAnsi(i);
        Console.WriteLine(s);
    }
    
    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.