gpt4 book ai didi

c# - Marshal.GetDelegateForFunctionPointer 失败

转载 作者:太空宇宙 更新时间:2023-11-04 02:15:49 24 4
gpt4 key购买 nike

我正在尝试从 .NET 应用程序调用 C 函数。事实上,我做了以下事情:

public unsafe class Simd
{
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void MatrixMultiplyDelegate(float* left, float* right);

public static MatrixMultiplyDelegate MatrixMultiply;

public static void LoadSimdExtensions()
{
string assemblyPath = "Derm.Simd.dll";

// Really calls 'LoadLibrary', 'GetProcAddress', 'FreeLibrary' from Kernel32.dll
IntPtr address = GetProcAddress.GetAddress(assemblyPath, "Matrix4x4_Multiply_SSE");

if (address != IntPtr.Zero) {
MatrixMultiply = (MatrixMultiplyDelegate)Marshal.GetDelegateForFunctionPointer(address, typeof(MatrixMultiplyDelegate));
}
}
}

加载的函数声明如下:

extern "C" {

void __declspec(dllexport) Matrix4x4_Multiply_SSE(float *left, float *right);

}

遗憾的是,我在调用 GetDelegateForFunctionPointer 时遇到以下异常:

InvalidFunctionPointerInDelegate:

Invalid function pointer 0xb81005 was passed into the runtime to be converted to a delegate.

我做错了什么?

最佳答案

首先,您确定您使用的是 __stdcall 调用约定吗?

C#默认使用__stdcall调用约定,如果不指定任何C++默认使用__cdecl!

extern "C" void __declspec(dllexport) __stdcall Matrix4x4_Multiply_SSE(float *left, float *right);

第二...如果您要使用该方法,则不能使用 FreeLibrary。加载一次库并将其保存在内存中。实际上,您永远不需要调用 FreeLibrary,操作系统会在您卸载程序时执行此操作。

第三...您确定通过对 P/Invoke 函数的委托(delegate)调用使用 SSE 乘法比在纯 C# 中执行它更快吗? P/Invoke 调用非常昂贵!

看看带有反射器的 XNA 矩阵乘法代码,它是用 C# 手写的,对于单个矩阵来说速度更快。

如果您需要将所有 10000 个矩阵相乘,那么我建议您在 dll 中使用 SSE 代码,它将在原生超优化代码中执行 10000 次乘法,但仅用于单个乘法,在 C# 中执行速度更快,无需 P/在没有任何委托(delegate)的情况下调用。

另请注意,SSE 指令的内存必须按 16 字节边界对齐,当然 C# 不遵循这种对齐方式 :) 特别是您将不得不处理喜欢在需要时移动内存的垃圾收集器。然后您需要使用固定数组或非托管内存。

关于c# - Marshal.GetDelegateForFunctionPointer 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7855962/

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