Project1

标题: 【RMXP DLL调用】DLL调用疑惑 [打印本页]

作者: 熊熊烈火雄壮    时间: 2013-12-12 19:51
标题: 【RMXP DLL调用】DLL调用疑惑
本帖最后由 熊熊烈火雄壮 于 2013-12-17 17:40 编辑

尝试用rmxp调用dll方法来调用自己封装的窗体以及较复杂的功能函数

在C#里简单的编了下:
using System;
using System.Collections.Generic;
using System.Text;

namespace LibForRM
{
    public class Class1
    {
        public int add(int a, int b)
        {
            return a + b;
        }
    }
}
导出  LibForRM.dll

然后在rmxp中执行:
$test_API = Win32API.new("Lib/LibForRM","add",'ii','i')
t=0
p t.to_s
t=$test_API.call(3,2)
p t.to_s

弹出
发生RuntimeError错误
GetProcAdress: add or AddA

错误原因我想是因为C#中有类的概念,需要先找到这个类,再来引用这个类中的成员函数
但是不知道如何操作。

请问该如何正确在rmxp中调用。

@癫狂侠客 @后知后觉 @灵魂の补给 @zhangbanxian @高手们

作者: 晴兰    时间: 2013-12-12 20:37
提示: 作者被禁止或删除 内容自动屏蔽
作者: 熊熊烈火雄壮    时间: 2013-12-12 20:55
晴兰 发表于 2013-12-12 20:37
错误原因是:C#的类和DLL的导出函数。。根本就是两码事。。。就像一个火鸡一个熊猫
这里有四种方法使用这个 ...

谢谢。

第1点我试试看。


第2点COM方式调用不太明白

第3点,函数面前加static修饰,函数就不属于这个类了,应该可以调用。但不同明白您提到的 RuntimeHost途径是怎样,在RM中如何写


第4点的话,是以下这种调用吗?
#=======================#
sizz = Win32API.new('shell32.dll','ShellExecuteA',%w(p p p p p i),'i')
sizz.call(0, 'open', 'Lib/libForRM.exe',0, 0, 1)
#=======================#

作者: 晴兰    时间: 2013-12-12 21:01
提示: 作者被禁止或删除 内容自动屏蔽
作者: 熊熊烈火雄壮    时间: 2013-12-12 21:09
晴兰 发表于 2013-12-12 21:01
第二点就是自己用CoCreateInstance来调用COM类厂构造对象,然后后面的就是COM系列API了
第三点是RuntimeH ...

我刚用VS2010建了个 VC++ /CLR类库
// vcTEST.h

#pragma once

using namespace System;

namespace vcTEST {


   static int sumup(int a,int b)
   {
           return a+b;
   }

}

在RM中
执行
$test_API = Win32API.new("Lib/vcTEST","sumup",'ii','i')
t=0
p t.to_s
t=$test_API.call(3,2)
p t.to_s

还是出现上述类似问题
请问您,我问题出在哪
作者: 晴兰    时间: 2013-12-12 21:12
提示: 作者被禁止或删除 内容自动屏蔽
作者: 熊熊烈火雄壮    时间: 2013-12-12 21:25
晴兰 发表于 2013-12-12 21:12
用extern "C" __declspec(dllexport) int __stdcall sumup(int a, int b);导出

static函数刚好是不导出 ...

// vcTEST.h

#pragma once

using namespace System;

namespace vcTEST {

extern "C" __declspec(dllexport) int __stdcall sumup(int a, int b);//导出


   int __stdcall sumup(int a,int b)
   {
           return a+b;
   }

}
生成调用后,依然出现问题。。。
作者: 熊熊烈火雄壮    时间: 2013-12-13 18:38
晴兰 发表于 2013-12-12 21:12
用extern "C" __declspec(dllexport) int __stdcall sumup(int a, int b);导出

static函数刚好是不导出 ...

在rm中调用,还是弹出
发生RuntimeError错误
GetProcAdress: sumup or sumupA错误

您能给一个例程吗?(dll工程+rm调用工程)


作者: tamashii    时间: 2013-12-13 22:40
问题出在CLR上。
CLR的dll不是标准的dll。Win32API的dll必须是标准的Win32 DLL,而CLR的dll必须在电脑中安装.Net Framework才可以。
另外就是CLR的dll结构也和Win32API的dll结构不同。就算是用C++.Net写出来的dll,没有命名空间和类,它的结构和普通C++写出来的dll也还是不一样。
作者: 晴兰    时间: 2013-12-14 17:00
提示: 作者被禁止或删除 内容自动屏蔽
作者: 熊熊烈火雄壮    时间: 2013-12-16 13:33
晴兰 发表于 2013-12-14 17:00
是这样的。。

首先,用这种方式导出的函数名会是_sumup@8,除非用#pragma或者def文件指示他生成sumup导 ...

谢谢!函数名导出后为 _sumup@8  这点太有用了!我改成这个后,调用成功了。
导出函数名都是这种形式么?  _原函数名@8

作者: 熊熊烈火雄壮    时间: 2013-12-17 12:20
晴兰 发表于 2013-12-14 17:00
是这样的。。

首先,用这种方式导出的函数名会是_sumup@8,除非用#pragma或者def文件指示他生成sumup导 ...

还想再请问下您,类能否dll输出?rm中如何调用类中的函数?


作者: 晴兰    时间: 2013-12-17 14:58
提示: 作者被禁止或删除 内容自动屏蔽
作者: 熊熊烈火雄壮    时间: 2013-12-17 17:11
晴兰 发表于 2013-12-17 14:58
类可以输出,但一般不能跨编译器调用,RM要直接用需要黑科技。不过,也可以为类写普通函数的的封装就不用 ...

非常感谢您的耐心解答,了然~




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1