这篇教程作为小玉米图文教程No.10的后续,所以序号定为10.5,跟No.10一样,这篇文章将会说明如何使用VC#来制作出GM8/GMS能调用的DLL插件。
同样是写在前面的注意事项:
1.在看此篇文章之前你需要先去查看No.10的文章,这里使用的所有资源都是No.10教程中使用的。
https://www.magecorn.com/p/279.shtml
2.此篇教程为输出DLL的简化版,无需更改IL文件,只要编写好CS文件后直接编译导出DLL即可直接给GM8/GMS使用。编译原理同No.10的文章一样。
在修改IL文件后成功的导出了一份DLL之后,跟某小狐狸又进行了一下研究,之后弄到了一个非常好用的nuget包来编译出可以直接调用的DLL。依然是之前的那个工程,这回我们要加入一个nuget包,在原有的代码基础上再添加一些代码,省去改写IL文件的麻烦步骤。
1.为你的类库项目添加nuget包
使用VS打开之前的项目,在点击菜单栏的工具->NuGet程序包管理器->程序包管理器控制台,打开Nuget控制台,
在控制台中输入以下命令来安装UnmanageExports程序包,我们要使用这个工具来导出DLL文件:
Install-Package UnmanagedExports
安装成功,控制台中会输出以下信息:
之后,在你的工程引用中会多出RGiesecke.DllExport.Metadata这个引用,我们就是需要用这货提供的一些东西来导出DLL文件。
2.改写cs代码,一次性输出可用DLL
之前我们已经写了一个cs文件,代码如下所示:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; //使用MessageBox需要的引用 namespace GMCSDLL { public class Class1 { // 需要导出的第一个函数:弹出信息框ShowMessage public static double ShowMessage(string message, string title){ var dialogResult = MessageBox.Show(message, title); return (double)dialogResult; } // 需要导出的第二个函数:获取a+b的值。 public static double getPlus(double a, double b) { return a + b; } } }
我们定义了两个需要导出的函数ShowMessage和getPlus,现在我们要修改一下这些代码,
①添加using引用
添加两条using引用:
using RGiesecke.DllExport; using System.Runtime.InteropServices;
②在每个要导出的函数前添加修饰,说明导出函数名
这里要在每个导出的函数前添加下面这样的代码:
[DllExport ("ShowMessage" ,CallingConvention = CallingConvention.Cdecl)]
其中,ShowMessage为导出的函数名CallingConvention.Cdecl为调用协定,如果你做过GM8调用dll那么一定不会对dll_cdecl和dll_stdcall陌生,这里就是定义这个东西的,CallingConvention除了可以设定为Cdecl外,还可以设定为StdCall,按照你得需要改就好。
在每个导出函数之前都加上这样的修饰,整体代码就是下面这个样子啦:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; //使用MessageBox需要的引用 using RGiesecke.DllExport; // 这行是新添加的using引用,用于使用UnmanageExports using System.Runtime.InteropServices; // 这行三十新添加的using引用,用于使用CallingConvention枚举 namespace GMCSDLL { public class Class1 { // 需要导出的第一个函数:弹出信息框ShowMessage // 下面的这行为新添加的代码,表示要导出ShowMessage函数,并指明导出函数名和调用约定 [DllExport ("ShowMessage" ,CallingConvention = CallingConvention.StdCall)] public static double ShowMessage(string message, string title){ var dialogResult = MessageBox.Show(message, title); return (double)dialogResult; } // 需要导出的第二个函数:获取a+b的值。 // 下面的这行为新添加的代码,表示要导出getPlus函数,并指明导出函数名和调用约定 [DllExport ("getPlus", CallingConvention = CallingConvention.Cdecl)] public static double getPlus(double a, double b) { return a + b; } } }
3.生成dll,并修复一些错误
点击菜单中的生成->生成解决方案来输出DLL文件。在这一过程中,可能会出现一些输出错误,像下面这样:
这种错误会出现在中文版的系统中,原因是UnmanageExports在生成IL文件时,一些注释被生成为中文导致UnmanageExports无法正常工作。这个问题是不会在日文和英文的操作系统上出现的,解决方案是有的,你可以把你得操作系统换成英文的~
但是这样就太麻烦了对吧,这里就需要拿出小狐狸的东西来修复一下咯!
在下面的地址中下载小狐狸提供的Unmanaged Exports修复版本
https://www.noisyfox.cn/397.html
鼠标右键解决方案资源管理器中最顶层的解决方案,选择在文件资源管理器中打开文件夹。
在文件管理器中依次进入packages->UnmanagedExports.1.2.7->tools,打开小狐狸提供的DllExport-Fixed-1.2.7.7z,将里面的RGiesecke.DllExport.dll和RGiesecke.DllExport.MSBuild.dll文件替换tools文件夹下的同名文件。
回到VS,对项目重新进行生成,然后就生成成功啦~
4.使用GM8/GMS对DLL进行调用
在这个DLL目录下创建一个GMK文件吧,然后写几句代码对新生成的DLL进行调用,我就直接上图了废话不多说了。
运行一下,看看结果:
行咯~那么这个GM8调用C#的DLL也就成功咯~GMS调用我就不试啦,反正代码都是这么写,当然,你也可以在GMS内写扩展,当调用其他语言写得DLL就行,并不是什么难事。