Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#封送C结构_C#_Struct_Pinvoke_Dllimport - Fatal编程技术网

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#程序 编辑:更好的方法:

我有一个C-C代码,可以工作:

h

c

.cs

这样,每当我需要将数据从C设置为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();
    }
}