C# 从c+调用c+;,返回值 我试图从C++调用C代码。所以我选择了COM互操作方式。现在我有了C代码: 和C++代码< /P> #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; }

C# 从c+调用c+;,返回值 我试图从C++调用C代码。所以我选择了COM互操作方式。现在我有了C代码: 和C++代码< /P> #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; },c#,c++,com,unmanaged,managed,C#,C++,Com,Unmanaged,Managed,当我尝试这个编译时,当然它说Write不接受2个参数。我看到了MSDN,他们有这样的例子,他们以这种方式获取返回值。所以我的问题是,如何获得函数的返回值?当我将呼叫更新为 piTest->Write("hi"); 在未处理的异常上执行失败。当我在没有返回值的情况下尝试此示例时,所以方法的返回值声明无效,一切正常。您的服务器代码正常,不需要使用out参数 客户机代码应该如下所示: long result = piTest->Write("hi"); virtual HRESULT

当我尝试这个编译时,当然它说Write不接受2个参数。我看到了MSDN,他们有这样的例子,他们以这种方式获取返回值。所以我的问题是,如何获得函数的返回值?当我将呼叫更新为

piTest->Write("hi");

在未处理的异常上执行失败。当我在没有返回值的情况下尝试此示例时,所以方法的返回值声明无效,一切正常。

您的服务器代码正常,不需要使用
out
参数

客户机代码应该如下所示:

long result = piTest->Write("hi");
virtual HRESULT __stdcall raw_Write(BSTR toWrite, long* pRetVal) = 0;
如果查看生成的
.tlh
文件,您将看到签名类似于:

long Write(_bstr_t toWrite);
这是一个生成的包装器代码,您可能会将其与原始COM调用混淆,原始COM调用也是
tlh
文件的一部分,如下所示:

long result = piTest->Write("hi");
virtual HRESULT __stdcall raw_Write(BSTR toWrite, long* pRetVal) = 0;
包装器更方便:它在内部调用原始COM调用并处理返回值-因此,返回值通常从函数返回(而不是作为
[out,retval]
参数),如果原始调用的结果表示错误(失败的
HRESULT
),则会引发
\u COM\u错误
异常


有关详细信息,您可以查看另一个生成的文件,该文件具有
tli
扩展名,其中包含wrapper方法的实现。

您的服务器代码正常,不需要使用
out
参数

客户机代码应该如下所示:

long result = piTest->Write("hi");
virtual HRESULT __stdcall raw_Write(BSTR toWrite, long* pRetVal) = 0;
如果查看生成的
.tlh
文件,您将看到签名类似于:

long Write(_bstr_t toWrite);
这是一个生成的包装器代码,您可能会将其与原始COM调用混淆,原始COM调用也是
tlh
文件的一部分,如下所示:

long result = piTest->Write("hi");
virtual HRESULT __stdcall raw_Write(BSTR toWrite, long* pRetVal) = 0;
包装器更方便:它在内部调用原始COM调用并处理返回值-因此,返回值通常从函数返回(而不是作为
[out,retval]
参数),如果原始调用的结果表示错误(失败的
HRESULT
),则会引发
\u COM\u错误
异常


有关详细信息,您可以查看另一个生成的文件,该文件具有
tli
扩展名,其中包含wrapper方法的实现。

我发现需要向c#添加参数,然后我可以使用第二个参数来实现函数,该函数将具有结果值。好的,对于Int,问题已经解决了,但是如何发送这样的字符串呢?您应该能够正常地返回一个值,而不是通过
[out]
参数。究竟什么是例外?您调试过托管调用了吗?我发现需要向c#添加参数,然后我可以使用第二个参数对函数进行调试,该函数将具有结果值。好的,对于Int,问题已经解决了,但是如何发送这样的字符串呢?您应该能够正常地返回一个值,而不是通过
[out]
参数。究竟什么是例外?你调试过托管呼叫吗?谢谢,我试过了。是的,我和HRESULT混淆了。当我从c#返回字符串时,是否需要在这里进行一些释放?如果是,如何返回?您没有返回字符串,因此没有要取消分配的内容。如果创建一个返回字符串的新方法(定义为
idl
定义中的
[out,retval]
参数),它符合标准COM规则,通常必须通过
SysFreeString
API取消分配它(例如,如果使用原始调用)。但是,
#import
还将生成一个“智能”包装器,该包装器将返回一个
bstr\u t
,该包装器负责为您解除分配,因此如果您使用该方法,则无需解除分配。谢谢,我尝试了。是的,我和HRESULT混淆了。当我从c#返回字符串时,是否需要在这里进行一些释放?如果是,如何返回?您没有返回字符串,因此没有要取消分配的内容。如果创建一个返回字符串的新方法(定义为
idl
定义中的
[out,retval]
参数),它符合标准COM规则,通常必须通过
SysFreeString
API取消分配它(例如,如果使用原始调用)。但是,
#import
还将生成一个“智能”包装器,该包装器将返回一个
bstr\u t
,该包装器负责为您解除分配它,因此如果您使用该方法,则没有什么可解除分配的。