2009-11-10 3 views
1

Я хотел бы вызвать эту функцию C++ из моих C# код:C#: вызов C DLL ++ с гольцом ** аргумента

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

назвать его в C++, я просто определить массив обугленных *:

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

Реализация функции в С ++:

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

Извините за мой английский.