gpt4 book ai didi

c# - C# 中的 PInvoke DLL

转载 作者:行者123 更新时间:2023-11-30 21:08:50 25 4
gpt4 key购买 nike

我想将结构传递给 C 函数,我编写了以下代码。

当我运行它时,第一个函数 - Foo1 正在运行,然后函数 Foo 出现异常。你能帮我理解问题是什么吗?...

C 代码:

typedef struct 
{
int Size;
//char *Array;
}TTest;

__declspec(dllexport) void Foo(void *Test);
__declspec(dllexport) int Foo1();

void Foo(void *Test)
{
TTest *X = (TTest *)Test;
int i = X->Size;
/*for(int i=0;i<Test->Size;Test++)
{
Test->Array[i] = 127;
}*/
}

int Foo1()
{
return 10;
}

C#代码:

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
[StructLayout(LayoutKind.Sequential)]
public class TTest
{
public int Size;
}

class Program
{
[DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto)]
public static extern void Foo(
[MarshalAs(UnmanagedType.LPStruct)]
TTest lplf // characteristics
);

[DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto)]
public static extern int Foo1();

static void Main(string[] args)
{
TTest Test = new TTest();
Test.Size = 25;

int XX = Program.Foo1();
Program.Foo(Test);
}
}
}

最佳答案

致反对者:这个答案解决了两个问题:调用约定的直接问题/MarhsalAs属性,以及他很快就会找到他的 TTest 的问题如果他采纳我的建议转TTest,参数将不起作用进入一个结构。

您的 native 代码要求 void* ,在 C# 中是一个 IntPtr .首先你应该定义 TTest作为结构而不是类。其次,您应该更改 Foo 的声明到:

[DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void Foo(IntPtr lplf);

第三,您应该固定 TTest使用 fixed关键字并将它的指针传递给 Foo .如果你正在使用一个类,你可以使用 Marhsal.StructureToPtr得到一个IntPtr来自你的 TTest .

这在两侧提供了相同的功能,可以传入指向任何类型的指针。您还可以使用要使用的所有类类型编写重载,因为它们都等于 void*。在本土方面。使用结构,您的参数将带有 ref 前缀.

我很好奇的是为什么您的 native 代码需要 void*而不是 TTest*当你在非托管代码中做的第一件事被强制转换为 TTest* .如果将参数切换为 TTest* ,然后提供相同的功能变得更简单。您的声明将变为:

[DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void Foo(ref TTest lplf);

您可以将该函数称为 Program.Foo(ref Test);

如果您正在使用该类,则 ref不是必需的,因为类是引用类型。

关于c# - C# 中的 PInvoke DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9369301/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com