我有一个C ++ .dll(无法对代码进行更改)我试图调用一个带有Struct类型的引用参数(也在.dll中定义)的函数。
该函数要求Struct具有' paramName'和' groupName'填充的字段,并根据这些字段,它将返回结构,并填充其余字段。
我没有收到任何编组错误,但是,库调用返回错误代码,调试日志显示它正在接收两个字符串字段的空字符串(请参阅下面的字段设置方式)。我的假设是这个结构的大小没有在托管和非托管表示之间对齐,因此结构不是blittable。
这是C ++方法签名:
int GetConfigs(int contextHandle, Configs* configs);
C ++ Configs结构:
struct Configs {
int myInt;
float myFloat;
bool flag;
char name[64];
char group[64];
}
C#函数包装器:
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int GetConfigs(int contextHandle, [MarshalAs(UnmanagedType.Struct), In, Out] ref Configs configs);
C#结构定义:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Configs
{
public int myInt;
public float myFloat;
[MarshalAs(UnmanagedType.U1)]
public bool flag;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string name;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string group;
}
根据Microsoft documentation,我已经声明C ++ char []用C#表示字符串,并编组为ByValTStr并设置大小。 同样来自Microsoft documentation:
最后,C#调用代码:
var configs = new Library.Configs
{
name = "testName",
group = "testGroup"
};
var returnCode = Library.GetConfigs(GetContextId(), ref configs);
返回代码作为失败代码返回,库调试输出文件显示struct参数:
name = []
(当我通过C#代码调试时,名称显然设置为我在调用时的预期)
而不是将字符串字段声明为
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string name;
我试过了:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] name;
但这也没有区别。
答案 0 :(得分:0)
float / double是抛出结构字节大小的东西 - 库期望一个4字节的浮点数,但默认情况下数据封送器将这些数字保持为8个字节。修复与上面评论中提到的布尔值一起解决了问题:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8">
var people = [];
$(document).ready(function() {
$.get('data.csv', function(data){
var lines = data.split('\n');
var properties = ["position", "name", "salary", "points", "team"]
for (var i = 0; i < lines.length; i++){
var person = lines[i].split(',');
var tmpPlayer = {}
for (var n = 0; n < person.length; n++){
tmpPlayer[properties[n]] = person[n]
}
people.push(tmpPlayer);
}
alert(people[1]["name"]);
render();
});
});
function render(){
alert(people[1].name);
}
</script>
</body>
</html>