【问题标题】:How do I pass the address of a c++ method in win32 app to a c# method with Action delegate parameter method如何将win32应用程序中的c++方法的地址传递给带有Action委托参数方法的c#方法
【发布时间】:2011-06-26 19:42:06
【问题描述】:

我有一个使用 C# 库win32 应用程序。

C# 库 有一个方法,其中Action<T> 委托是一个参数,如下所示:

public NetSocket(Action<int, int, string> action)

我在 win32 应用程序中有一个 ref 类,其方法与 Action 委托签名相匹配。

我该如何将此方法作为上述NetSocket 方法中的Action 参数传递?


您的解决方案似乎有效,但是在将 win32 应用程序中的操作委托方法的 System:Sting^ 输入参数与操作委托的 String 输入参数匹配时出现编译错误在 C# 代码中。 c# 代码中的 Action 委托使用 String 作为输入参数,win32 代码中的 Action 委托方法尝试使用 System::String^ 进行匹配,但不起作用。

// 赢得 32 个应用程序 - void ServerClass::ActionMethod(int iCommand, int iClientIndex, System::String^ message)

// win32 app -server = gcnew NetSockets::NetSocket(gcnew Action(this,&amp;ServerClass::ActionMethod));

// csharp - public NetSocket(Action&lt;int, int, string&gt; action)

我需要使用一些编组方法来匹配 win32 代码中使用的System::String 与 C# 代码中使用的字符串吗?我是通过System::String 错误还是必须做其他事情?我必须怎么做才能将System::String^ 消息参数与字符串参数匹配?
谢谢


经过更正,我尝试了您的解决方案,但出现以下错误:

1 错误 C3352: 'void ServerClass::ActionMethod(int,int,System::String ^)' : 指定的函数与委托类型不匹配 'void (void)'


@Ben:越来越近了。现在,当我使用您的解决方案编译代码时,我得到一个内部编译错误,如下所示:

错误 C1001:编译器发生内部错误。
c:\program 文件 (x86)\microsoft visual studio 9.0\vc\include\msclr\marshal.h 49 1 win32project

代码在使用 Framework 3.5 而不是 4.0 的 Visual Studio 10 中编译

我检查了发生内部编译的行,错误发生在这里 marshal.h 文件中的第 49 行:

_size = ::WideCharToMultiByte(CP_THREAD_ACP, WC_NO_BEST_FIT_CHARS, _pinned_ptr, _str->Length, NULL, 0, NULL,NULL);
if (_size == 0 && _str->Length != 0)
{
    throw gcnew System::ArgumentException(_EXCEPTION_WC2MB);
}

我猜这个错误的发生是因为 c++ 代码中的 String::String^ 输入参数可能没有被编组到 c# 代码,或者相反。

我不确定我需要修复代码的 c++ 端还是代码的 C# 端。 有什么想法吗?

我想可以只制作一个 c++ dll 并让 c# 库导入该库并调用 c++ dll 中的一个方法,然后让 win32 应用程序加载 c++ dll,但是拥有一个库似乎很奇怪当 c++ dll 使用 c# 库作为参考时,加载 w++ dll。


我检查了发生内部编译的行,错误发生在这里 marshal.h 文件中的第 49 行。

_size = ::WideCharToMultiByte(CP_THREAD_ACP, 
                              WC_NO_BEST_FIT_CHARS,
                              _pinned_ptr, 
                              _str->Length, 
                              NULL, .
                              0, 
                              NULL,
                              NULL);
if (_size == 0 && _str->Length != 0)
{
    throw gcnew System::ArgumentException(_EXCEPTION_WC2MB);
}

我猜这个错误的发生是因为 c++ 代码中的 String::String^ 输入参数可能没有被编组到 c# 代码,或者相反。 不确定 id 我需要修复代码的 c++ isde 或代码的 C# 端。

【问题讨论】:

    标签: c# visual-c++ c++-cli


    【解决方案1】:

    如果是原生 C++ 函数,请使用 Marshal.GetDelegateForFunctionPointer

    如果您使用的是 C++/CLI,听起来像是(并且您应该重新标记问题),您需要以下内容:

    NetSocket(gcnew Action<int,int,String^>(this, &ServerClass::ActionMethod))
    

    【讨论】:

    • @steve 请不要向 cmets 添加代码。将其添加为问题的编辑。
    • 经过更正我尝试了您的解决方案,它给出了以下错误Error 1 error C3352: 'void ServerClass::ActionMethod(int,int,System::String ^)' : the specified function does not match the委托类型'void(void)'
    • @steve:HTML 格式化程序吃掉了你的通用参数。我会修正我的答案以匹配。
    • -1, Marshal.GetDelegateForFunctionPointer 在给定泛型委托类型时抛出。
    • @ildjarn:如果为真,那将是一个错误,无论如何,事实证明@steve 正在使用 C++/CLI。但最初写的问题是Action(非通用),与C++/CLI无关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 2016-11-10
    相关资源
    最近更新 更多