我在使用Marsolling C DLL结构时遇到麻烦 这是C DLL中的代码
// cbool.h
#ifndef CBOOL_H
#define CBOOL_H
#define false 0
#define true !false
typedef unsigned char boolean; /* false=0, otherwise true */
#endif
// test.h
#include "cbool.h"
typedef struct
{
bool a;
bool b;
float c;
} BoolStruct;
extern BoolStruct BStruct;
__declspec(dllexport) void GetBStruct (BoolStruct* bs);
__declspec(dllexport) void SetBStruct (BoolStruct* bs);
// test.c
#include "test.h"
BoolStruct BStruct;
void GetBStruct (BoolStruct* bs)
{
*bs = BStruct;
}
void SetBStruct (BoolStruct* bs)
{
BStruct = *bs;
}
和C#
public struct BoolStruct
{
public bool a;
public bool b;
public float c;
}
BoolStruct bs;
[DllImport(DLL_NAME, EntryPoint = "GetBStruct")]
public static extern void GetBStruct(ref BoolStruct bs);
[DllImport(DLL_NAME, EntryPoint = "SetBStruct")]
public static extern void SetBStruct(ref BoolStruct bs);
bs.a = true;
bs.c = 0.5F;
... set
...get
但是使用float类型设置并且获取值是正确的,而当我设置boll(例如true)时,我总是收到错误 你能救我吗?
答案 0 :(得分:0)
我尝试了您的代码和建议,但不能工作...... 我通过编辑文件CBool暂时解决了
typedef int boolean; /* false=0, otherwise true */
它有效! 在另一个类似的情况下
typedef struct {
// don't work!
//char TestString[5];
// work!
int TestString[5];
} MyStruct;
和C#
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct MyStruct
{
public MyStruct(uint i)
{
// ......
TestString = new char[5];
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst=5)]
public char[] TestString;
}
似乎char和unsigned是问题,或者我做错了什么,否则,但不知道是什么
答案 1 :(得分:-1)
尝试:
[StructLayout(LayoutKind.Sequential)]
public struct BoolStruct
{
[MarshalAs(UnmanagedType.U1)]
public bool a;
[MarshalAs(UnmanagedType.U1)]
public bool b;
public float c;
}
By default the bool
is marshaled as an Int32
in .NET.
您应该在执行PInvoke时指定StructLayout
(但请注意struct
it isn't necessary:要减少与自动值相关的布局相关问题,请执行C# ,Visual Basic和C ++编译器为值类型指定顺序布局。)
啊,你忘记了CallingConvention
:对于C函数通常是Cdecl
:
[DllImport("CPlusPlusSide.dll", EntryPoint = "GetBStruct", CallingConvention = CallingConvention.Cdecl)]
public static extern void GetBStruct(ref BoolStruct bs);
[DllImport("CPlusPlusSide.dll", EntryPoint = "SetBStruct", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetBStruct(ref BoolStruct bs);
(测试x86和x64)