c# - 将字符串从 DLL 传递到 C#

标签 c# c++ dll c++-cli parameter-passing

我有一个 C# 应用程序,它使用 CLI DLL 从非托管 C++ 库访问函数。我的问题是我无法从 C++ 库中获取要正确传递给 C# 应用程序的文本。到目前为止,我的代码如下:

C#

[DllImport("Wrapper.dll", EntryPoint = "GetNameLength", CallingConvention = CallingConvention = CallingConvention.Cdecl)]
public static extern bool _GetNameLength( int index, out int size);
[DllImport("Wrapper.dll", CharSet = CharSet.Ansi, EntryPoint = "GetName", CallingConvention = CallingConvention.Cdecl)]
public static extern bool _GetName( out Stringbuilder name, int size, int index);

private void TestFunction()
{
    int size = 0;
    _GetNameLength(2, out size);
    StringBuilder str = new StringBuilder(size + 1);

    _GetName(out str, str.Capacity, 2);

    btnName.Text = str.ToString();
}

命令行

// In the header.
#define DllExport __declspec( dllexport)

extern "C" {
    DllExport bool __cdecl GetNameLength( int index, int& size);
    DllExport bool __cdecl GetName( char* name, int size, int index);
};


// In the '.cpp'.
bool __cdecl GetNameLength( int index, int& size) {
    if( gp_app == nullptr)
        return false;

    gp_app->GetNameLength( index, size);

    return true;
}

bool __cdecl GetName( char* name, int index, int size) {
    if( gp_app == nullptr)
        return false;

    const char* n = "";
    n = gp_app->GetName( index);

    name = new char[size];
    strcpy( name, n);

    return true;
}

C++

// In the header.
class App {
    void GetNameLength( int index, int& size);
    const char* GetName( int index);
};

// In the '.cpp'.
void App::GetNameLength( int index, int& size) {
    if( index >= 0 && index < gs_namesCount)
        size = strlen( gs_names[index]);
}

const char* App::GetName( int index) {
    if( index >= 0 && index < gs_namesCount)
        return gs_names[index];

    return nullptr;
}

我能够调试到 DLL 中,我发现它确实正确地复制了名称,即使我只使用 name = const_cast<char*>( n) 也是如此。 (当我使用字符串而不是 StringBuilder 时),但由于某种原因,该值没有从 DLL 返回到 C#。

我读到一个可能的原因是因为 C++ 可能使用 ASCII 字符而 C# 使用 16 位字符,并且解决这个问题的方法是包含 CharSet = CharSet.Ansi以便在返回到 C# 时正确编码,但这显然没有帮助。

谁能告诉我我做错了什么?


解决方案:
使用 public ref class代替命名空间并使用 void Foo( [Out] String^ %name) 声明函数确保 using namespace System::Runtime::InteropServices;包括在内。

最佳答案

这告诉我你实际上有一个托管的 c++ dll。

if( gp_app == nullptr)
    return false;

如果是这样,您可以导出托管类并使用 String 作为该方法的参数。

检查这个:http://msdn.microsoft.com/library/windows/apps/hh699870.aspx

关于c# - 将字符串从 DLL 传递到 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21490928/

相关文章:

c# - 使用 TOP 1 插入和删除语句

c# - 为什么我的 WCF 客户端在调用引发事件的 WCF 服务器中的方法后超时?

c++ - 为什么我们在建库的时候要设置符号链接(symbolic link)呢?

c# - 我怎样才能防止我的已编译库的用户查看代码?

c# - 无论可执行文件的位置如何,都在命令提示符下运行 C# 程序?

c++ - 有没有办法在 xcode 上使用 c++0x?我想使用 gcc 4.4 或更高版本

c++ - 如何绘制自定义形状的元素?

c++ 引用 - 是否分配了内存?

c# - 无法加载文件或程序集。即使它位于正确的位置并且构建良好

c# - 将相同的命名空间拆分到不同的程序集中有什么好的理由?