2009-11-10 4 views
1

Je voudrais appeler cette fonction C++ de mon code C#:C#: appeler C++ DLL avec l'argument char **

void GetArrayOfNames(char** names, int nbOfNames); 

Pour appeler en C++, je définir simplement un tableau de char *:

char* aNames[20]; 

et allouer chaque nom dans une boucle:

for(int i-0; i<20; i++) 
{ 
    aNames[i] = new char[50]; 
} 

appellent ensuite:

GetArrayOfNames(aNames, 20); 

Dans mon code C#, je:

[DllImport("MyDLL.dll")] 
unsafe static extern void GetArrayOfNames(char** ppNames, int nbOfNames); 

Maintenant, comment dois-je faire l'allocation de mémoire et appeler GetArrayOfNames? En outre, aucun moyen de ne pas déclarer ma fonction comme "dangereuse"?

Répondre

0

Cela a fini par travailler:

static extern int GetArrayOfNames(IntPtr[] astr, int iLength);

Et appelé/configuration comme ceci:

IntPtr[] intArr = new IntPtr[200]; 
for (int i = 0; i < intArr.Length; i++) 
{ 
    intArr[i] = Marshal.AllocHGlobal(256); 
} 

int nbOfNames = 2; 
GetArrayOfNames(intArr, nbOfNames); 

Et de remettre dans une chaîne:

string tmp; 
tmp = Marshal.PtrToStringAnsi(intArr[i]); 
2

Probablement:

 
static extern void GetArrayOfNames([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr] StringBuilder[] args, int count); 

// Call using 
StringBuilder[] arr = new StringBuilder[20]; 
for (int i = 0; i < arr.Length; i++) 
{ 
    arr[i] = new StringBuilder(50); 
} 
GetArrayOfNames(arr, arr.Length); 
1

Si je comprends bien char** est juste une référence à la chaîne. J'ai créé un petit test pour moi et il a bien fonctionné:

class Program 
{ 
    [DllImport("TestCppLib.dll", CharSet = CharSet.Ansi, EntryPoint = "[email protected]@[email protected]", CallingConvention=CallingConvention.Cdecl)] 
    extern static int fnTestCppLib(ref string s); 
    static void Main(string[] args) 
    { 
     var s = "some"; 
     var t = fnTestCppLib(ref s); 
     Debug.Assert(s == "test"); 
    } 
} 

La mise en œuvre de la fonction en C++ est:

TESTCPPLIB_API int fnTestCppLib(char ** str) 
{ 
    *str = "test"; 
    return 42; 
} 
0

Puis-je vous aider? mon exemple de code en C++:

//CamMethods.cpp: 
#include <iostream> 
using namespace std; 
#include "CamPS.h" 

namespace Export { 
    char * CameraPS::CamStart(char *s){ 
     return "teste"; 
    }; 
} 

//CamPs.h 
namespace Export{ 
    class CameraPS 
    { 
    public: 
     _declspec(dllexport) char * _stdcall CamStart(char *s); 
    }; 
} 

et en C# i appeler:

using UnityEngine; 
using System; 
using System.Collections; 
using System.Runtime.InteropServices; 

public class DllTeste : MonoBehaviour 
{ 
    public int x; 
    [DllImport ("PS_Cam.dll", EntryPoint="CamStart", CallingConvention = CallingConvention.StdCall)] 
    private static extern IntPtr CamStart (int s);//i can put <string> in same place of <int> 


    void Start() 
    { 

    } 

    void Update() 
    { 
//  IntPtr a = CamStart(x); 
//  string b = Marshal.PtrToStringAnsi(a); 
//  Debug.Log(b); 
     Debug.Log(Marshal.PtrToStringAnsi(CamStart(x))); 
    } 
} 

Désolé pour mon anglais.

Questions connexes