3

Despite all the questions, I can't find a suitable answer for doing this.

My goal is to fill a string[] with the use of a DLL that returns a char**.

DLL Declaration :

extern "C" SHTSDK_EXPORT int GetPeerList(SHTSDK::Camera *camera, int* id, int id_size, char** name, int name_size, int* statut, int statut_size);

My import :

[DllImport(libName)]
static public extern int GetPeerList(IntPtr camera, IntPtr id, int id_size, IntPtr name, int name_size, IntPtr statut, int statut_size);

My use in C# code :

StringBuilder[] name = new StringBuilder[nbPeer];
for (int i = 0; i < nbPeer; i++)
{
     name[i] = new StringBuilder(256);
}
//Alloc peer name array
GCHandle nameHandle = GCHandle.Alloc(name, GCHandleType.Pinned);
IntPtr pointeurName = nameHandle.AddrOfPinnedObject();

int notNewConnection = APIServices.GetPeerList(cameraStreaming, pointeurId, 

nbPeer, pointeurName, nbPeer, pointeurStatut, nbPeer);

// Now I'm supposed to read string with name[i] but it crashes

What did I miss? I really searched on the other topics, I thought this one could work, but still crashing.

Thanks.

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
Evans Belloeil
  • 2,413
  • 7
  • 43
  • 76
  • 1
    I would suggest making a mixed assembly ( visual C++ with a cli support ) and use this as a wrapper on native ( C++ ) functions. It is far more easier than what you've done right now. – mrogal.ski Aug 31 '17 at 10:18
  • Maybe it could be helpful? https://stackoverflow.com/questions/11508260/passing-stringbuilder-to-dll-function-expecting-char-pointer#11509815 – R2RT Aug 31 '17 at 17:45

1 Answers1

0

I suggest you developing a tiny C++/CLI bridging layer. The purpose of this C++/CLI bridge is to take the string array returned by the DLL in the form of char** raw pointers, and convert it to a .NET string array, that can be consumed in your C# code as a simple string[].

The C++/CLI version of C# string[] (string array) is array<String^>^, e.g.:

array<String^>^ managedStringArray = gcnew array<String^>(count);

You can use the usual syntax with operator[] (i.e. managedStringArray[index]) to assign each string to the array.

You may write some code like this:

// C++/CLI wrapper around your C++ native DLL
ref class YourDllWrapper
{
public:
    // Wrap the call to the function of your native C++ DLL,
    // and return the string array using the .NET managed array type
    array<String^>^ GetPeerList( /* parameters ... */ )
    {
        // C++ code that calls your DLL function, and gets
        // the string array from the DLL.
        // ...

        // Build a .NET string array and fill it with
        // the strings returned from the native DLL 
        array<String^>^ result = gcnew array<String^>(count);
        for (int i = 0; i < count; i++)
        {
            result[i] = /* i-th string from the DLL */ ;
        }

        return result;
    }

    ...
}

You may find this article on CodeProject on C++/CLI arrays an interesting reading as well.


P.S. The strings returned from your native DLL are in the form of char-strings. On the other hand, .NET strings are Unicode UTF-16 strings. So you need to clarify what encoding is used to represent text in your native strings, and convert to UTF-16 for .NET strings.

Mr.C64
  • 41,637
  • 14
  • 86
  • 162