C#封送C结构
我有一个C-C代码,可以工作: h c .cs 这样,每当我需要将数据从C设置为C时,我必须调用C#封送C结构,c#,struct,pinvoke,dllimport,C#,Struct,Pinvoke,Dllimport,我有一个C-C代码,可以工作: h c .cs 这样,每当我需要将数据从C设置为C时,我必须调用void SetMyStruct,反之亦然,如果我想将数据从C(从void test更新)设置为C,我必须调用GetMyStruct。我必须每秒钟做50次 有没有办法避免每次都调用SetMyStruct和GetMyStruct?我想使用SetMyStruct一次,然后将所有更改从和反映到。我不知道这是否可行。您可以使用不安全的和指针来实现这一点 您需要编译启用“不安全”的C#程序 编辑:更好的方法:
void SetMyStruct
,反之亦然,如果我想将数据从C(从void test更新)设置为C,我必须调用GetMyStruct
。我必须每秒钟做50次
有没有办法避免每次都调用
SetMyStruct
和GetMyStruct
?我想使用SetMyStruct
一次,然后将所有更改从和反映到。我不知道这是否可行。您可以使用不安全的和指针来实现这一点
您需要编译启用“不安全”的C#程序
编辑:更好的方法:
向库中添加以下函数:
__declspec(dllexport) void GetMyStructRef (MyStruct** s);
void GetMyStructRef(MyStruct** s)
{
*s = &mystruct;
}
在C#中:
旧答案:
unsafe class MyClass : IDisposable
{
[DllImport(DLL_NAME, EntryPoint = "GetMyStruct")]
protected static extern void GetMyStruct(MyStruct* s);
[DllImport(DLL_NAME, EntryPoint = "SetMyStruct")]
protected static extern void SetMyStruct(MyStruct* s);
GCHandle handle;
MyStruct* structRef;
public void MyClass()
{
//we need to get a pinned reference to your struct
handle = GCHandle.Alloc(new MyStruct(), GCHandleType.Pinned);
structRef = (MyStruct*)handle.AddrOfPinnedObject().ToPointer();
SetMyStruct(structRef);
}
public void Dispose()
{
//We need to free the handle to release memory
//GC will not collect it without this
handle.Free();
}
}
尝试从struct
更改为class
,并删除各种ref
关键字。对于这样一个非常简单的结构,这在技术上是可行的。您可以公开一个返回MyStruct*的函数,以返回指向c的指针。并使用C#程序中的unsafe
代码直接访问其a和b成员。但您确实犯了一个错误,您没有检查是否需要优化此代码。每秒只叫60次,你绝对不会。这是一个非常快的代码,你可以每秒数亿次调用它。@Olaf只是出于好奇:你为什么从这个问题中删除了c
标记?@PJvG:因为它不是问c,而是问c。如果任何调用C函数的问题都允许使用C标记,则必须将其添加到每个问题中。这不是它的用途,如果你想要一个包含非托管资源的类,你需要让它更复杂一些。
public struct MyStruct
{
public float a;
public float b;
}
[DllImport(DLL_NAME, EntryPoint = "GetMyStruct")]
protected static extern void GetMyStruct(ref MyStruct s);
[DllImport(DLL_NAME, EntryPoint = "SetMyStruct")]
protected static extern void SetMyStruct(ref MyStruct s);
__declspec(dllexport) void GetMyStructRef (MyStruct** s);
void GetMyStructRef(MyStruct** s)
{
*s = &mystruct;
}
[DllImport(DLL_NAME, EntryPoint = "GetMyStructRef")]
protected static extern void GetMyStructRef(ref MyStruct* s);
MyStruct* data;
GetMyStructRef(ref data);
Console.WriteLine($"{data->a} {data->b}");
unsafe class MyClass : IDisposable
{
[DllImport(DLL_NAME, EntryPoint = "GetMyStruct")]
protected static extern void GetMyStruct(MyStruct* s);
[DllImport(DLL_NAME, EntryPoint = "SetMyStruct")]
protected static extern void SetMyStruct(MyStruct* s);
GCHandle handle;
MyStruct* structRef;
public void MyClass()
{
//we need to get a pinned reference to your struct
handle = GCHandle.Alloc(new MyStruct(), GCHandleType.Pinned);
structRef = (MyStruct*)handle.AddrOfPinnedObject().ToPointer();
SetMyStruct(structRef);
}
public void Dispose()
{
//We need to free the handle to release memory
//GC will not collect it without this
handle.Free();
}
}