将数据类型从C#封送到C++; 我目前正在使用一个非托管C++库中的一些业务逻辑来处理一个C(.net框架4.7.2)应用程序。我尝试从C到C++之间来回传递数据(互操作)。我可能不使用C++/CLI,我的项目中不允许使用公共语言运行时
它对int很好。不幸的是,当我尝试发送另一个数据类型时,我得到了一个转换错误,例如float 4.2f变为1,字符串“fourtytwo”变为-1529101360 我的C#代码如下所示:将数据类型从C#封送到C++; 我目前正在使用一个非托管C++库中的一些业务逻辑来处理一个C(.net框架4.7.2)应用程序。我尝试从C到C++之间来回传递数据(互操作)。我可能不使用C++/CLI,我的项目中不允许使用公共语言运行时,c#,c++,marshalling,C#,C++,Marshalling,它对int很好。不幸的是,当我尝试发送另一个数据类型时,我得到了一个转换错误,例如float 4.2f变为1,字符串“fourtytwo”变为-1529101360 我的C#代码如下所示: // works fine, creates an instance of TestClass var test = TestProxy.Wrapper_Create("test"); // int, works fine, a = 42 var a = TestProxy.TryInt(test
// works fine, creates an instance of TestClass
var test = TestProxy.Wrapper_Create("test");
// int, works fine, a = 42
var a = TestProxy.TryInt(test, 42);
// float, problem, b = 1
var b = TestProxy.TryFloat(test, 4.2f);
// string, problem, c = -159101360
var c = TestProxy.TryString(test, "fourtytwo");
public static class TestProxy
{
private const string coreDLL = "test.core.dll";
[DllImport(coreDLL, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr Wrapper_Create(string name);
[DllImport(coreDLL, EntryPoint = "?TryInt@TestClass@@XXX@X", CallingConvention = CallingConvention.ThisCall)]
public static extern int TryInt(IntPtr instance, int n);
[DllImport(coreDLL, EntryPoint = "?TryFloat@TestClass@@XXX@X", CallingConvention = CallingConvention.ThisCall)]
public static extern int TryFloat(IntPtr instance, float n);
[DllImport(coreDLL, EntryPoint = "?TryString@TestClass@@XXX@X", CallingConvention = CallingConvention.ThisCall)]
public static extern int TryString(IntPtr instance, string n);
}
HRESULT TryString( TestClass *instance, BSTR i, BSTR *o )
< P>我调用C(本地)(非托管)C++代码的C互操作代理类看起来是这样的:
// works fine, creates an instance of TestClass
var test = TestProxy.Wrapper_Create("test");
// int, works fine, a = 42
var a = TestProxy.TryInt(test, 42);
// float, problem, b = 1
var b = TestProxy.TryFloat(test, 4.2f);
// string, problem, c = -159101360
var c = TestProxy.TryString(test, "fourtytwo");
public static class TestProxy
{
private const string coreDLL = "test.core.dll";
[DllImport(coreDLL, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr Wrapper_Create(string name);
[DllImport(coreDLL, EntryPoint = "?TryInt@TestClass@@XXX@X", CallingConvention = CallingConvention.ThisCall)]
public static extern int TryInt(IntPtr instance, int n);
[DllImport(coreDLL, EntryPoint = "?TryFloat@TestClass@@XXX@X", CallingConvention = CallingConvention.ThisCall)]
public static extern int TryFloat(IntPtr instance, float n);
[DllImport(coreDLL, EntryPoint = "?TryString@TestClass@@XXX@X", CallingConvention = CallingConvention.ThisCall)]
public static extern int TryString(IntPtr instance, string n);
}
HRESULT TryString( TestClass *instance, BSTR i, BSTR *o )
<我的本地(非托管)C++看起来是这样的:
头文件:
#ifdef TESTCORE_EXPORTS
#define TESTCORE_API __declspec(dllexport)
#endif
#pragma once
extern "C"
{
class TESTCORE_API TestClass
{
private:
char* name;
public:
TestClass(char*);
int TryInt(int);
float TryFloat(float);
char* TryString(char*);
};
TESTCORE_API TestClass* Wrapper_Create(char* name);
}
实现文件:
#include "stdafx.h"
#include "TESTCore.h"
TestClass::TestClass(char* n)
{
name = n;
}
int TestClass::TryInt(int n)
{
return n; // works fine
}
float TestClass::TryFloat(float n)
{
return n; // something goes wrong here
}
char* TestClass::TryString(char* n)
{
return n; // something goes wrong here
}
extern "C"
{
TESTCORE_API TestClass * Wrapper_Create(char* name)
{
return new TestClass(name);
}
TESTCORE_API int TryInt(TestClass * instance, int n)
{
if (instance != NULL)
{
return instance->TryInt(n);
}
}
TESTCORE_API float TryFloat(TestClass * instance, float n)
{
if (instance != NULL)
{
return instance->TryFloat(n);
}
}
TESTCORE_API char* TryString(TestClass * instance, char* n)
{
if (instance != NULL)
{
return instance->TryString(n);
}
}
}
你知道如何正确地将浮点、字符串从C→C++返回到?
谢谢大家! C++没有标准的ABI。在DLL上使用C++类是个好主意,即使在两边都有相同的语言。 有更好的办法 < > > >用全局函数、CDECL或STDCLAK替换您的<代码>代码> C++ /Cord>类方法(但注意C++和C++有不同的缺省值,如果您不做任何处理,C++将使用CDECL,C将导入STDCALL)。您可以在第一个参数中传递类的“this”指针,即C#中的IntPtr,就像您现在所做的一样。另外,如果您要编写
extern“C”
或使用模块定义文件,它们将具有人类可读的名称
[marshallas(UnmanagedType.LPTStr)]
应用于参数。将[返回:marshallas(UnmanagedType.LPTStr)]
应用于函数。在DllImport中指定PreserveSig=true
。最后,修改C++代码返回一个字符串的副本,即调用<代码> StrLon < /C> >代码> COTASKMeMeloLC/<代码(不要忘记<代码> 0”<代码>,然后<代码> StrcPy < /Cord>
处理字符串的更简单方法如下:
// works fine, creates an instance of TestClass
var test = TestProxy.Wrapper_Create("test");
// int, works fine, a = 42
var a = TestProxy.TryInt(test, 42);
// float, problem, b = 1
var b = TestProxy.TryFloat(test, 4.2f);
// string, problem, c = -159101360
var c = TestProxy.TryString(test, "fourtytwo");
public static class TestProxy
{
private const string coreDLL = "test.core.dll";
[DllImport(coreDLL, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr Wrapper_Create(string name);
[DllImport(coreDLL, EntryPoint = "?TryInt@TestClass@@XXX@X", CallingConvention = CallingConvention.ThisCall)]
public static extern int TryInt(IntPtr instance, int n);
[DllImport(coreDLL, EntryPoint = "?TryFloat@TestClass@@XXX@X", CallingConvention = CallingConvention.ThisCall)]
public static extern int TryFloat(IntPtr instance, float n);
[DllImport(coreDLL, EntryPoint = "?TryString@TestClass@@XXX@X", CallingConvention = CallingConvention.ThisCall)]
public static extern int TryString(IntPtr instance, string n);
}
HRESULT TryString( TestClass *instance, BSTR i, BSTR *o )
<>至少有<代码> CCOMBSTR 和