BCB6 调用C# DLL
最近项目涉及第三方接口调用。第三方是用C#实现的WCF服务。而我们的程序是使用的BCB6开发。因此,打算将与WCF的通讯包含在C#的类库中,给BCB6调用。BCB6 是无法直接调用C#的DLL,但可以通过C#编写一个COM组件,然后BCB调用这个COM组件来调用。
- 用C#编写COM
大体步骤是
- 新建一个类库项目
|
|
- 设置Assemblyinfo.cs

- 设置项目属性

- 编写代码
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; //1添加Rumtime.InteropServices 程序集引用 using System.Windows.Forms; //2为了演示,所以加入了forms引用 namespace ComImpTest { [Guid("3CD116D4-18A1-4504-921B-57C053BAD618")] //3主菜单->工具->创建GUID产生 public interface IComInterface //4必须先定义接口 { [DispId(1)] //5每一个函数或者属性都需要指定DispID void Hello(string name); [DispId(2)] int Add(int x,int y); [DispId(3)] string COMINFO{get;} } [Guid("1A8EB38C-E732-49B2-A897-B40FFD744E3D")] public class ComImp : IComInterface //6编写一个实现接口的类 { public void Hello(string name) { Console.WriteLine("你好"+name); MessageBox.Show("你好"+name,"C# dll 弹出界面"); } public int Add(int x, int y) { return x + y; } public string COMINFO { get { return "com 测试"; } } } } |
- 编译得到DLL 和 TLB

- BCB编写调用
- 首先BCB的开发环境中需要安装.NET FrameWork ,这里都是用的.NET FrameWork 4.0,安装之后,
在如图的目录会得到RegAsm.exe(一定要用安装后得到的RegAsm 从其他地方复制的RegASM可能存在版本不兼容),
这个在注册COM的时候要用到。

- 建立一个BCB控制台工程
- 吧RegAsm.exe(我们是为了注册方便),前面编译得到的 ComImpTest.tlb 、ComImpTest.dll 复制到BCB工程的EXE
输出目录。(这也不是必须的,本质上COM只要能注册,然后BCB功能能找到TLB创建代理类即可)

- 用管理员启动命令行,注册ComImpTest.dll

其本质是吧这个COM类注册到了注册表中。向系统进行了发布。
- 用BCB 产生代理类
打开BCB 工程,选择主菜单 projectàimport type library



得到代理类

包含这个头文件,我们就可以调用了。
但是这里不知道是BCB的bug,还是兼容性的问题,BCB产生的ComImp代理类的GUID是错误的。

正确的GUID 应该是编写C#dll 时产生的Guid
|
[Guid("1A8EB38C-E732-49B2-A897-B40FFD744E3D")] |
我们只需要替换这个Guid即可,如果不这么做,调用时HRESULT会返回找不到实现接口。

- BCB 调用COM的代码
- 在控制台工程中,加入代理类的头文件 ComImpTest_tlb.h
- 代码如下
|
//--------------------------------------------------------------------------- #pragma hdrstop #include <iostream> #include <vcl.h> //注意,iostream要在 vcl.h 前面定义,否则cout<<AnsiString 报错 #include "Comimptest_tlb.h" using namespace std; //--------------------------------------------------------------------------- #pragma argsused int main(int argc, char* argv[]) { HRESULT hr; //初始化COM CoInitialize ( NULL ); //创建智能指针命名空间在头文件Comimptest_tlb.h中可以查找到 //接口智能指针的定义也能查找到 Comimptest_tlb::IComInterfacePtr ptr; //创建实例,ComImp 的声明,也能在头文件中查找到。 hr = ptr.CreateInstance(__uuidof (Comimptest_tlb::ComImp)); if(hr == S_OK) { //调用ADD方法 cout << ptr->Add (1, 2)<<endl; //调用Hello方法,在bcb中Widestring 对应 c#的 string WideString name = "Zakk wylde 和奥兹"; ptr->Hello(name.c_bstr()); //调用COMINFO属性,这里COM进行了名字改变,这些函数都可以在头文件中查到原型定义。 BSTR outp = NULL; ptr->get_COMINFO(&outp); //因为是宽字符,所以要转换为AnsiString进行输出 cout<<AnsiString(outp)<<endl; } CoUninitialize (); system("pause"); return 0; } |


4 用vc调用COM
用VC调用C#的COM 就没有这么多事情。下面是VC调用的代码,
将ComImpTest.tlb 和 ComImpTest.dll 拷贝到 VC工程的debug目录下。然后用import指令(BCB 无法用import识别,估计是不兼容)
// testCOM3.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;
#import "../debug/ComImpTest.tlb" int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr;
//初始化COM
CoInitialize ( NULL );
//创建智能指针
ComImpTest::IComInterfacePtr ptr; //创建实例
hr = ptr.CreateInstance(__uuidof (ComImpTest::ComImp)); if(hr == S_OK)
{
cout << ptr->Add (,)<<endl;
ptr->Hello(L"VC++ 调用");
cout<<ptr->COMINFO<<endl;
} CoUninitialize ();
system("pause");
return ;
} //---------------------------------------------------------------------------
BCB6 调用C# DLL的更多相关文章
- c# 调用c++DLL方法及注意事项
引用命名空间 using System.Runtime.InteropServices 调用方法: 一.静态加载 用DllImprot方式来加载c++DLL.如下格式: //对应c++方法 //voi ...
- 在.net中调用Delphi dll的Pchar转换
Pchar是非托管代码,要在.net中调用Delphi dll中的功能,请使用MarshalAs属性告知.net调用PInvoke去转换.net中标准的string类型.如果Delphi dll是De ...
- Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()
Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...
- C#调用C++ DLL类方法
C++的优势在于高效灵活,C#的优势在于简单易用,两者结合起来对项目开发来说是件好事,而且C++不容易反编译,也保障了代码的安全性,如果一些核心算法使用C#编写,那么保密就是一个问题. C++生成的D ...
- paip.java 调用c++ dll so总结
paip.java 调用c++ dll so总结 ///////JNA (这个ms sun 的) 我目前正做着一个相关的项目,说白了JNA就是JNI的替代品,以前用JNI需要编译一层中间库,现在JNA ...
- C#调用C++ DLL 文件
说来惭愧,都注册一年多了,却没有发表过一篇正式的博文,中间很多学习的过程也没有记录下来.如今到了一个新的环境,也有了学习的机会,一定要把每天的收获记录一下. 要做的东西需要引用C++编写的DLL,刚开 ...
- LR调用动态链接库DLL
什么是动态库? 动态库一般又叫动态链接库(DLL),是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库. 动态链接提供了一种方法 ,使进程可以 ...
- C#调用C++ Dll
现在项目基本都是旁边C++的哥们做好dll扔给我,然后我调用.好久之前晚上down了一份c#调用c++dll的方法,出处早已经遗忘.闲来无事,放上来好了.原作者看到后可以留言,我会把您链接放上的,帮了 ...
- 【JNI】OPUS压缩与解压的JNI调用(.DLL版本)
OPUS压缩与解压的JNI调用(.DLL版本) 一.写在开头: 理论上讲,这是我在博客园的第一篇原创的博客,之前也一直想找个地方写点东西,把最近做的一些东西归纳总结下,但是一般工程做完了一高兴就把东西 ...
随机推荐
- 安卓计数器类APP推荐
1. Thing Counter - Google Play 上的应用 可添加多个计数器,同一页面展示,一行一个,操作直观方便: 可以更改计数器颜色,使页面更美观. 每个计数器有详情和历史记录 详情: ...
- mysql配置优化的参数
1.MySQL数据库高效优化解析 Mysql优化是一项非常重要的工作,而且是一项长期的工作,曾经有一个为位DBA前辈说过:mysql的优化,三分配置的优化,七分sql语句的优化. Mysql的优化: ...
- 日常工作问题解决:du命令详解
目录 1.导读 1.1 命令格式 1.2 命令功能 1.3 命令参数 2.实例 2.1 实例1:显示目录或者文件所占空间 2.2 实例2:显示指定文件所占空间 2.3 实例3:查看指定目录所占空间 2 ...
- 乐字节Java反射之四:反射相关操作
大家好,乐字节小乐继续为Java初学者讲述Java基础知识.上次说到乐字节Java反射之三:方法.数组.类加载器,这次是Java反射之四:反射相关操作 1.操作属性 //1.获取Class对象 Cla ...
- java源码 -- LinkedHashSet
问题 (1)LinkedHashSet的底层使用什么存储元素? (2)LinkedHashSet与HashSet有什么不同? (3)LinkedHashSet是有序的吗? (4)LinkedHashS ...
- Linux下的静态库与动态库的生成与调用
静态库与动态库 静态函数库 这类库的名字一般是libxxx.a,xxx为库的名字.利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行 ...
- laravle6.0-IOC-DI浅谈
1.什么是IOC,DI IOC(Inversion of Control)控制反转:ioc意味着,你将自己设计好的对象交给容器来控制,而不是传统的在你的对象内部直接控制.比如: 人 操控 手机 做一些 ...
- Excel计算、统计函数
Excel计算.统计函数 1.=SUMPRODUCT(array1,[array2]...) 返回对应的区域或数组的乘积之和. 默认运算是乘法,但加.减和除也可能. 2.=COUNT 计数 3.= ...
- 2020年AI、CV、NLP顶会最全时间表
2020年AI.CV.NLP顶会最全时间表 2019-09-01 14:04:19 weixin_38753768 阅读数 40 2020 AI.CV.NLP主流会议时间表,包含会议举办的时间.地 ...
- (三)easyUI之树形组件
一.同步树 1.1 概念 所有节点一次性加载完成 1.2 案例 1.2.1 数据库设计 1.2.2 编码 index.jsp <%@ page language="java" ...
