question

BananaLin-4905 avatar image
0 Votes"
BananaLin-4905 asked BananaLin-4905 commented

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

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.





dotnet-csharpc++
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

RLWA32-6355 avatar image
1 Vote"
RLWA32-6355 answered BananaLin-4905 commented

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
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

It's work! Thank you!

0 Votes 0 ·