VC2015编写的DLL给其他语言调用

(1)用C++builder6调用DLL

用VC2015创建包含MFC库的DLL,如果是给C++Builder6使用,步骤如下:
1、工程属性==》C++==》高级==》调用约定  选项为:__stdcall (/Gd)

2、VC++2015中的函数声明如下:
   extern "C" __declspec(dllexport)  VOID __stdcall CreateMeter(const char* szTypeName);

3.VC++2015的def文件,EXPORTS可以不用写,因为C++Builder6不用到这个.lib文件
  不过,我发现要导出函数,需要在def字声明,否则在其他语言中找不到函数,提示错误.

4.在C++Builder6中,需要重新导出DLL的引导库.lib,方法如下:
  implib my.lib my.dll

  在BCB6工程中引入my.lib,同时添加函数声明,也就是VC2015DLL中的函数声明(与第2步相同)


(2)用Delphi7调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
unit  ScaleWeight_dll;
interface
        procedure   CreateMeter(xktype: PChar ;
        No: integer ;
        Comm: integer ;
        baud: integer ;
        parity: Char ;
        databit: integer ;
        stopbit: integer
        );stdcall;external  'YuComm.dll' ;
        //获取重量字符串
        function   GetWeight( buff : pchar ;index : integer  1 ): PChar ;stdcall;
        external  'YuComm.dll' ;
        //写串口
        procedure  WritePort( buff : array  of  byte ;index : integer  0 );stdcall;
        external  'YuComm.dll' ;
        function  ClosePort(index : integer = 1 ): integer ;stdcall;external  'YuComm.dll' ;
        //name 'ClosePort1';
 
        //辅助函数
        //缓取缓冲区数据量
        function  GetBuffLength(index : integer  = 0 ): integer ;stdcall;
        external  'YuComm.dll' ;
        //或取通信状态;true串口打开但通信中断,false通信正常
        function  GetStatus(index : integer  = 0 ): boolean ;stdcall;external  'YuComm.dll' ;
        //清除缓冲区数据
        //procedure Clear(index :integer =0);stdcall;external 'YuComm.dll';
        //获取原始数据
        function   GetSourceData( buff :pbyte;index : integer  0 ): integer ;stdcall;
        external  'YuComm.dll' ;
        
implementation
 
end .

将上面文件保存为扩展名为pas的文件,添加到delphi7工程中.

(3)在VB6中调用DLL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Private  Declare  Function  CreateMeter  Lib  "YuComm" ( ByVal  name  As  String , _
ByVal  No  As  Integer , _
ByVal  port  As  Integer , _
ByVal  baud  As  Integer , _
ByVal  parity  As  Integer , _
ByVal  databit  As  Integer , _
ByVal  stopbit  As  Integer As  Boolean '需要添加一个返回值声明,即使不需要
Private  Declare  Function  GetWeight  Lib  "YuComm" ( ByVal  buff  As  String
Optional  ByVal  index  As  Integer  = 1)  As  Long
Private  Declare  Function  GetStatus  Lib  "YuComm" ( Optional  ByVal  index  As  Integer  = 1) 
As  Integer
Private  Declare  Function  ClosePort  Lib  "YuComm" ( Optional  ByVal  index  As  Integer  = 1) 
As  Boolean
 
  
Private  Sub  Command1_Click()
   Dim  name  As  String
   Dim  port  As  Integer
   Dim  baud  As  Integer
   
   name = Combo1.Text
   port =  CInt (Text1.Text)
   baud =  CInt (Text2.Text)
   CreateMeter name, 1, port, baud, 110, 8, 1
   
End  Sub
 
Private  Sub  Command2_Click()
   ClosePort (1)
End  Sub
 
Private  Sub  Command3_Click()
 
End  Sub
 
Private  Sub  Timer1_Timer()
    Dim  re  As  Boolean
    
    re = GetStatus(1)
    If  re =  True  Then
      Label2.Caption =  "串口打开成功"
    Else
      Label2.Caption =  "串口打不成功"
    End  If
    
    Dim  buff1   As  String
    buff1 = Space(100)
    Call  GetWeight(buff1, 1)
    Label1.Caption = buff1
    
End  Sub

在XP平台下,用VB6调用,请用release方式编译,否则VB6会提示找不到相应的DLL文件,即所这个文件就在运行目录下

在VB中调用,声明函数时应加上返回值,即使DLL中这个函数没有返回值.返回值的类型可任意

(4)在C#中调用DLL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
public  partial  class  Form1 : Form
     {
         //========================================================================
         //1、创建仪表,并打开仪
         [DllImport( "YuComm.dll" )]
         public  static  extern  bool  CreateMeter( string  xktype, int  no, int  comm,
         int  baud, int  parity, int  databit, int  stopbit);
         //2、读取仪表重量,多台仪表时,参数为索引
         [DllImport( "YuComm.dll" )]
         public  static  extern  string  GetWeight(StringBuilder weight,  int  index = 1);
         //写串口
         [DllImport( "YuComm.dll" )]
         public  static  extern  void  Write( ref  byte  buff, int  index = 1);
         //3、关闭串口
         [DllImport( "YuComm.dll" )]
         public  static  extern  void  ClosePort(  int  index=1);
     
 
 
         //ScaleWeight辅助功能函数:获取缓冲区数据个数
         [DllImport( "YuComm.dll" )]
         public  static  extern  int  GetBuffLength( int  index = 1);
         //获取通信状态:false通信正常 ,true通信中断
         [DllImport( "YuComm.dll" )]
         public  static  extern  bool  GetStatus( int  index=1);
         //辅助功能函数:读取原始数据流
         [DllImport( "YuComm.dll" )]
         public  static  extern  int  GetSourceData( ref  byte  buff,  int  index = 1);
         //辅助功能函数:清除缓冲区
         //[DllImport("YuComm.dll")]
         //public static extern void Clear(int index=1);
        //===================================================================
         public  Form1()
         {
             InitializeComponent();
         }
 
         private  void  button1_Click( object  sender, EventArgs e)
         {
            xktype  = comboBox1.Text;
            szComm    = textBox1.Text;
            szBaud = textBox2.Text;
 
            bool  re = CreateMeter(xktype, 1, Convert.ToInt32(szComm), 
            Convert.ToInt32(szBaud),  'n' , 8, 1);
            if  (re)
            {
                label1.Text =  "串口状态:打开成功" ;
            }
            else
            {
                label1.Text =  "串口状态:打开不成功" ;
            }
         }
 
         private  void  button2_Click( object  sender, EventArgs e)
         {
             ClosePort(1);
             label1.Text =  "串口状态:串口关闭" ;
         }
 
         private  void  timer1_Tick( object  sender, EventArgs e)
         {
             StringBuilder buff =  new  StringBuilder(255); 
             GetWeight(buff,1);
             label2.Text = buff.ToString();
             buff =  null ; //释放
 
             label5.Text =  "缓冲区中数据量:" + GetBuffLength().ToString();
 
             bool  re = GetStatus();
             if  (re)
                 label4.Text =  "通信状态:通信数据流正常" ;
             else
                 label4.Text =  "通信状态:通信数据流中断" ;
 
             byte [] data =  new  byte [1024];
             int  c = GetSourceData( ref  data[0],1);
             richTextBox1.Clear();
             for  ( int  i = 0; i < c; i++)
             {
                 richTextBox1.Text += data[i].ToString( "X2" ) + " " ;
             }
             data =  null ;
 
         }
 
         private  void  button3_Click( object  sender, EventArgs e)
         {
             byte [] buff =  new  byte [1024];
             string  a =  "hello" ;
             BitConverter.ToString(buff);
             Write( ref  buff[0], 1);
             buff =  null ;
         }
 
         private  void  button4_Click( object  sender, EventArgs e)
         {
             timer1.Enabled = !timer1.Enabled;
             if  (timer1.Enabled)
                 button4.Text =  "暂停" ;
             else
                 button4.Text =  "开始" ;
         }
 
     }

在XP上运行,请使用release方式编译发布,否则调用DLL中的函数时会报错!

















本文转自Chinayu201451CTO博客,原文链接:http://blog.51cto.com/9233403/2063081 ,如需转载请自行联系原作者



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用VS2015编译和调用动态链接库dll 1. 首先建工程,选择dll,记得勾上“导出符号” 后面不用自己搞那些宏定义会省事很多。 建立工程myDll,记得勾上“导出符号” 类型选择dll 2. IDE自动生成的代码已经把整个架构弄好了,其中和项目同名的.h和.cpp文件就是我们自己写代码的地方了。我想写的dll是导出一个类,在这里我就直接在它自动生成的CmyDll类上面改了。 myDll.h myDll.cpp 在mydll.h和mydll.cpp中给类添加成员函数 //mydll.h class MYDLL_API CmyDll { public: CmyDll(void); // TODO: 在此添加您的方法。 int myFunction(int a, int b); }; //mydll.cpp int CmyDll::myFunction(int a, int b) { return a*b; } 3.编译的时候我选择了release,这里可以用默认的debug也行 在mydll.h和mydll.cpp中给类添加成员函数 最后生成解决方案后产生的mydll.lib和mydll.dll就是我们需要的二进制文件了。lib文件是编译是要用的,而dll调用这个库的程序运行时需要的。 调用dll 1.重新建立一个工程 这回选择普通的控制台程序就行了。我建了个名为myDllCall的工程。 2.把库的头文件include进来,以及连接lib文件 其中 include进来的 myDll.h 和 **#pragma comment()**的lib根据自己的路径写。 #include "stdafx.h" #include "../../myDll/myDll/myDll.h" //头文件 #pragma comment(lib,"../../myDll/Release/myDll.lib") //调用自己写的外部库 #include int main() { CmyDll mydll; int a, b; std::cin >> a >> b; std::cout << mydll.myFunction(a, b) <> a >> b; std::cout << mydll.myFunction(a, b) << std::endl; return 0; } 3.dll放到可执行文件同一目录下面 刚刚的代码直接编译没问题,运行会报错. 直接编译没问题,运行会报错 原因是dll要和生成的可执行文件在同一个目录下,我把mydll.dll放进去之后就解决了。 我们成功的在自己的工程里调用了外部的类 可以看到我们成功的在自己的工程里调用了外部的类。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值