2009-11-10 121 views
1

DLL我想从我的C#代码中调用这个C++函数:C#调用C++使用char **参数

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

要调用它在C++中,我只是定义的char *数组:

char* aNames[20]; 

和环型分配每个名字:

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

然后拨打电话:

GetArrayOfNames(aNames, 20); 

在我的C#代码,我有:

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

现在,我该怎么办了内存的分配和调用GetArrayOfNames?此外,任何不必将我的函数声明为“不安全”的方式?

回答

0

这结束了工作:

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

并号召/设置是这样的:

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

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

并放回一个字符串:

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

大概:

 
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

据我所知char**只是对字符串的引用。我创建了自己的一个小测试,它工作得很好:

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"); 
    } 
} 

的功能在C++实现是:

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

我可以帮你吗?在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); 
    }; 
} 

,并在C#我打电话:

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))); 
    } 
} 

对不起,我的英语水平。