c# - 从 C# 调用带有 char* 的 C++ 函数

标签 c# c++ dll clr static-libraries

我有一个包含静态 C++ 库的 CLR C++ dll。 我有以下类(class):

#pragma once

#include <windows.h>
#include <sddl.h>

#include <LibEx.h>
using namespace System;
#using <mscorlib.dll>

namespace LIB_WrapperNamespace {

    public ref class LIB_WrapperClass
    {
    public:
        BOOL WINAPI T_LibEx_ConsoleConnect(IN DWORD num1, IN LPWSTR Name)
        {
            return LibEx_ConsoleConnect(num1,Name);
        }
        };
} 

在 C# 中,我添加了对库的引用

LIB_WrapperNamespace.LIB_WrapperClass myLib = new LIB_WrapperNamespace.LIB_WrapperClass();

现在如何调用这个函数,如何将字符串发送到char*?来自 C#:

string myName = "NAME";
myLib.T_LibEx_ConsoleConnect(1,**myName**);

最佳答案

API 应该将该参数公开为 wchar_t*,因此您需要在 C# 中提供一个指针值。尝试以下操作

IntPtr ptr = IntPtr.Zero;
try { 
  ptr = Marshal.StringToCoTaskMemUni("NAME");
  unsafe { 
    myLib.T_LibEx_Consoleconnect(1, (char*)(ptr.ToPointer()));
  }
} finally { 
  if (ptr != IntPtr.Zero) { 
    Marshal.FreeCoTaskMem(ptr);
  }
}

不幸的是,由于您已经公开了带有原始指针值的方法,所以如果没有 unsafe 代码,就无法从 C# 中使用它。另一种方法是公开一个重载,比如一个 string^。这可以从 C# 中使用,C++/CLI 代码可以处理从 string^LPWSTR

的编码
BOOL WINAPI T_LibEx_ConsoleConnect(DWORD num1, String^ Name) { 
   IntPtr ip = Marshal::StringToHGlobalUni(Name);
   BOOL ret = T_LibEx_ConsoleConnect(num1, static_cast<LPWSTR>(ip.ToPointer()));
   Marshal::FreeHGlobal(ip);
   return ret;
}

// From C#
myLib.T_LibEx_ConsoleConnect(1, "NAME");

关于c# - 从 C# 调用带有 char* 的 C++ 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17953842/

相关文章:

c# - Selenium C# ElementNotVisibleException : element not interactable but the element is actually visible

c# - 为什么有时无法收到使用 Azure SendGrid 从 ASP.Net core Web 应用程序发送的电子邮件

c# - 使用 Math.Pow 时出现 "cannot convert double to float"错误

C++ 内存分配

c++ - 为什么要在定义宏之前取消定义它们?

c - 如何从 Dart 扩展 dll 中抛出自定义错误?

c# - asp.net mvc 和云 : how are global data structures distributed

c# - 如何在应用程序中使用引用同一 dll 的不同版本的两个 dll?

从 Go 语言调用的 C# DLL(类库)函数

c++ - 如何在 makefile 中包含和编译库