C#:使用 char** 参数调用 C++ DLL

Posted

技术标签:

【中文标题】C#:使用 char** 参数调用 C++ DLL【英文标题】:C#: calling C++ DLL with char** argument 【发布时间】:2009-11-10 23:07:06 【问题描述】:

我想从我的 C# 代码中调用这个 C++ 函数:

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?另外,有什么方法不必将我的函数声明为“不安全”?

【问题讨论】:

【参考方案1】:

大概:

static extern void GetArrayOfNames([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr] StringBuilder[] args, int count); // 调用使用 StringBuilder[] arr = new StringBuilder[20]; for (int i = 0; i

【讨论】:

【参考方案2】:

据我了解,char** 只是对字符串的引用。我为自己创建了一个小测试,效果很好:

class Program

    [DllImport("TestCppLib.dll", CharSet = CharSet.Ansi, EntryPoint = "?fnTestCppLib@@YAHPAPAD@Z", 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;

【讨论】:

【参考方案3】:

这最终奏效了:

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

【讨论】:

【参考方案4】:

我能帮你吗?我的 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)));
    

对不起我的英语。

【讨论】:

以上是关于C#:使用 char** 参数调用 C++ DLL的主要内容,如果未能解决你的问题,请参考以下文章

C#调用C++的dll库怎么传递结构体中不定长度的char数组

调用从 c# 返回 char* 的 c++ dll 函数。无法使用 DllImport()

C#调用dll时的类型转换总结

C#怎么调用C++的dll?

关于delphi调用C++的DLL中char*参数的问题

c#调用C、C++编写的dll