C# Dll - 导出函数

3
我正在尝试创建一个带有几个可导出函数的C# dll。然后,我想让一个C++/非托管程序加载该.dll文件并调用其中特定的导出函数。
我正在使用Robert Giesecke's Unmanaged Exports,但似乎它不起作用。
我在调试器中运行了非托管程序,它成功执行了"LoadLibrary()",但当它尝试"GetProcAddress(test_start)"时,调用失败并返回零。
这是我的C#代码:
    using System.Runtime.InteropServices;
    using RGiesecke.DllExport;
    using etc...; 

    namespace test_dll
    {

        public class Class1
         {  

              [DllImport("kernel32.dll")]
              public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

              [DllExport("test_start", CallingConvention = CallingConvention.Cdecl)]
              public static void test_start()
              {
                    MessageBox.Show("It works","YES");
              }

         }
    }

.dll编译正常,CPU匹配(x86),但一旦加载了C# DLL,非托管程序就无法获取导出函数地址。目前还比较基础,我只是想让它能够工作。以后我还需要导入。请帮忙解决,因为nuget包的文档相当简单。谢谢。

在调用 GetProcAddress 失败后,GetLastError 返回什么?我假设您正在向 GetProcAddress 传递正确的模块句柄。您是否查看了生成的 DLL 的 EXPORTS 部分,以确保 test_start 的拼写(包括大小写)与您期望的相同? - Jim Mischel
3
据我所知,“DllExport”一直是一个非常棘手的解决方案。更好的解决方法是使用C++/cli作为托管和非托管代码之间的桥梁。然后,您可以公开非托管函数,该函数将调用C#中的托管函数。参见此MSDN博客文章,了解如何执行此操作的示例。 - Scott Chamberlain
除了@Scott的建议之外,另一个选择是将您的库构建为COM服务器,将您的类导出为COM对象。这有点重量级,但提供了更通用的解决方案(即,您的COM服务器将与各种客户端代码场景一起工作)。为了调试您当前的问题,您可以使用dumpbin.exe和/exports选项,以查看第三方DllExport和构建操作是否已为您导出。 - Peter Duniho
使用Dumpbin.exe /exports命令在您的DLL上查看导出名称。它应该是“_test_start”(前导下划线)以匹配Cdecl。 - Hans Passant
你使用什么C++开发工具? - M.Hassan
1个回答

2
嘿,实际上我一直都做得很好。
奇怪的是,Robert Giesecke的Unmanaged Exports忽略了第一个导出项?
所以,我创建的任何导出项都在那个之下工作并被识别。
我使用CFF Explorer检查了有效的导出项,除了第一个之外,其他所有导出项都在那里。因此,我只是在顶部留下了一个空白的导出项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接