从 C++ 调用 C#,return 值
call c# from c++, return value
我正在尝试从 C++ 调用 C# 代码。所以我选择了COM Interop方式。现在我有了 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 %d\n", lResult);
// Uninitialize COM.
CoUninitialize();
return 0;
}
当我尝试编译时,当然它说 Write 不接受 2 个参数。我看到了 MSDN,他们在那里有这样的例子,他们以这种方式获取 return 值。所以我的问题是,如何获取函数的 return 值?当我更新对
的调用时
piTest->Write("hi");
比未处理的异常执行失败。当我在没有 returning 值的情况下尝试这个示例时,方法的 return 值声明无效,然后一切正常。
您的服务器代码没有问题,您不需要使用 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 调用并处理 return 值 - 因此,return 值通常是从函数 returned(而不是作为 [out, retval]
参数),如果原始调用的结果表示错误(失败的 HRESULT
),则抛出 _com_error
异常。
详情可以查看另一个生成的文件,扩展名为tli
,其中包含包装器方法的实现。
我正在尝试从 C++ 调用 C# 代码。所以我选择了COM Interop方式。现在我有了 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 %d\n", lResult);
// Uninitialize COM.
CoUninitialize();
return 0;
}
当我尝试编译时,当然它说 Write 不接受 2 个参数。我看到了 MSDN,他们在那里有这样的例子,他们以这种方式获取 return 值。所以我的问题是,如何获取函数的 return 值?当我更新对
的调用时piTest->Write("hi");
比未处理的异常执行失败。当我在没有 returning 值的情况下尝试这个示例时,方法的 return 值声明无效,然后一切正常。
您的服务器代码没有问题,您不需要使用 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 调用并处理 return 值 - 因此,return 值通常是从函数 returned(而不是作为 [out, retval]
参数),如果原始调用的结果表示错误(失败的 HRESULT
),则抛出 _com_error
异常。
详情可以查看另一个生成的文件,扩展名为tli
,其中包含包装器方法的实现。