从 C++ 调用 C#,返回值
call c# from c++, return value
我正在尝试从C++调用C#代码。所以我选择了 COM 互操作方式。现在我有 C# 代码:
namespace ToBeCalled
{
[Guid("9329feaf-b293-4093-a7d8-6128f52b30a6")]
[ComVisible(true)]
public interface IInterface
{
int Write(string toWrite);
}
}
namespace ToBeCalled
{
[Guid("e4105e40-2d6b-4b7c-ae42-d2f9c405a2a0")]
[ComVisible(true)]
public class ClassYouWantToUse : IInterface
{
public int Write(string toWrite)
{
System.Console.WriteLine(toWrite);
return 1;
}
}
}
和 C++ 代码
#import "...\ToBeCalled.tlb"
int _tmain(int argc, _TCHAR* argv[])
{
// Initialize COM.
HRESULT hr = CoInitialize(NULL);
// Create the interface pointer.
ToBeCalled::IInterfacePtr piTest(__uuidof(ToBeCalled::ClassYouWantToUse));
long lResult = 0;
// Call the Add method.
piTest->Write("hi", &lResult);
wprintf(L"The result is %dn", lResult);
// Uninitialize COM.
CoUninitialize();
return 0;
}
当我尝试这个编译时,它当然说 Write 不需要 2 个参数。我看到了MSDN,他们有这样的例子,他们以这种方式获取返回值。所以我的问题是,如何获取函数的返回值?当我将呼叫更新到
piTest->Write("hi");
比在未处理的异常上执行失败。当我在没有返回值的情况下尝试此示例时,因此方法的返回值声明无效,一切正常。
您的服务器代码正常,不需要使用 out
参数。
客户端代码应如下所示:
long result = piTest->Write("hi");
如果您查看生成的.tlh
文件内部,您将看到签名类似于:
long Write(_bstr_t toWrite);
这是一个生成的包装器代码,您可能会将其与原始 COM 调用混淆,后者也是 tlh
文件的一部分,如下所示:
virtual HRESULT __stdcall raw_Write(BSTR toWrite, long* pRetVal) = 0;
包装器更方便:它在内部调用原始 COM 调用并处理返回值 - 因此,返回值通常从函数返回(而不是作为[out, retval]
参数),如果原始调用的结果表示错误(失败的HRESULT
),则会抛出_com_error
异常。
有关详细信息,您可以查看另一个扩展名为tli
生成的文件,其中包含包装方法的实现。
相关文章:
- 从python中调用C++函数并获取返回值
- 调用CreateProcess()并获取字符串的返回值
- "co_yield"是否可以在恢复协程时从调用方返回值?
- 了解在返回值之前和之后使用 EAX 的函数调用
- 实例化对象并调用方法,使用单行语法在 C# 或 C++ 中返回值?
- 在 OOP 中,调用函数返回值还是直接调用值更快?
- 使用布尔值稍后返回还是调用函数并立即返回更快?C++
- 当设置对象等于另一个函数的返回值时,为什么要调用移动构造函数/分配
- 为什么未调用具有常量参考返回值的超载方法
- 为循环中多次调用的函数返回值预分配内存的正确方法是什么
- 如何调用外部程序并在 C/C++ 中获取多个返回值
- 重载运算符->() 以更改被调用函数的返回值
- C++如何在模板中推断可调用对象的类型(参数列表和返回值)
- 如何调用函数,传递函子的返回值(可能为 void)
- x86-64 调用约定中的返回值
- 如何在关机调用后在 UDP recvfrom() 调用中获取返回值 0
- 为什么在传递重载运算符的返回值时不调用复制构造函数
- 如何从调用的函数获取返回值,该函数在 TBB 中的另一个线程中执行
- 如何使用其他函数的返回值调用重载函数
- 如何根据布尔类型成员函数的返回值调用结构成员函数