调用外部DLL,如:DelphiC++Java的DLL的调用方法,给出代码片段?
来源:互联网 发布:有益网络 编辑:程序博客网 时间:2024/06/05 17:08
//指示该属性化方法由非托管动态链接库 (DLL) 作为静态入口点公开。
System.Runtime.InteropServices.DllImportAttribute
有时需要写上路径的如[DllImport(@"C:\OJ\Bin\Judge.dll")]这样指定DLL的绝对路径就可以正常装载。
假如没有路径的话,DllImport会按照顺序自动去寻找的地方:
1、exe所在目录 2、System32目录 3、环境变量目录
² Delphi_未测试
[ DllImport ( "WZFSE.dll" , CharSet = CharSet.Ansi ,
CallingConvention = CallingConvention.StdCall )]public static extern void InitDll(IntPtr handle, bool methodAddress);
第一个参数是指要引用DLL的名字, 这个名字应该是个常量(否则会出错)。
CharSet 参数指示用在入口点中的字符集。如果未指定 CharSet,则使用默认值 CharSet.Auto。
CallingConvention 参数指示入口点的调用约定。如果未指定 CallingConvention,则使用默认值 CallingConvention.Winapi。
写一个函数就相应的应用起对应的DLL。
[DllImport ( "user32.dll" , CharSet = CharSet.Ansi ,
CallingConvention = CallingConvention.StdCall )]public static extern void MoveWindow ( IntPtr handler , int x , int y ,
int width , int height , bool repaint );
如何将Dephi的窗体显示在自己的页面中(且不能显示Delphi窗体的标题栏,实现无缝的结合)。
http://www.cnblogs.com/elivn/archive/2010/11/19/1881686.html
Delphi一般类型对应如下:
Dephi-->C#
intger -->int longint -->long
pchar -->string THandle -->IntPtr
Char[]-->string
例:
Delphi DLL中的方法:
function GetXMLByNet(piChartType: integer; psXMLFileName: PChar; psPriChartFileName: PChar; psSecChartFileName: PChar; out psPriHotMsg: PChar; out psSecHotMsg: PChar): integer; stdcall;export;
private class DrawChartFromDll { private const string _fileDll = @"Chart.dll"; //定义DLL文件名,此文件路径要加到系统Path中
[DllImport ( _fileDll , EntryPoint = "GetXMLByNet" , CharSet = CharSet.Ansi ,
CallingConvention =CallingConvention.StdCall )]
//调用非托管Dll,GetXMLByNet是ChartAccess.dll公开的函数名称 public static extern int GetXMLByNet ( int piChartType , string psXMLFileName ,
string psPriChartFileName , string psSecChartFileName , string psPriHotFileName , string psSecHotFileName );}
调用:DrawChartFromDll.GetXMLByNet(m_chartType, _xmlFileName,...);
² C++
类型对照:
BSTR --------- StringBuilder LPCTSTR --------- StringBuilder
LPCWSTR --------- IntPtr handle---------IntPtr
hwnd-----------IntPtr char *----------string
int * -----------ref int int &-----------ref int
void *----------IntPtr unsigned char *-----ref byte
Struct需要在C#里重新定义一个Struct
CallBack回调函数需要封装在一个委托里,delegate static extern int FunCallBack(string str);
注意在每个函数的前面加上public static extern +返回的数据类型,如果不加public ,函数默认为私有函数,调用就会出错。
1. 数据类型转换问题
2. 指针或地址参数传送问题
例如C++的原有函数是:
int __stdcall FunctionName(unsigned char param1, unsigned short param2)
其中的参数数据类型在C#中,必须转为对应的数据类型。如:
[DllImport ( "COM DLL path/file" )]
extern static int FunctionName ( byte param1 , ushort param2 );
因为调用的是__stdcall函数,所以使用了P/Invoke的调用方法。其中的方法FunctionName必须声明为静态外部函数,即加上extern static声明头。我们可以看到,在调用的过程中,unsigned char变为了byte,unsigned short变为了ushort。变换后,参数的数据类型不变,只是声明方式必须改为.NET语言的规范。
例:指针、引用类型
int __stdcall FunctionName(unsigned char ¶m1, unsigned char *param2);
//在C#中对其进行调用的方法是: [DllImport("file")] extern static int FunctionName(ref byte param1, ref byte param2);
例:二维数组
//C++编译的DLL里方法的声明:
_declspec(dllexport) int device_EPC_fetch(
char Ebuffer[50][33],int length,int device_id,int *tag_num);
//C#调用: [DllImport("MyFunDll.dll", EntryPoint = "device_EPC_fetch", CharSet = CharSet.Ansi)] public static extern int device_EPC_fetch( byte[,] arg1, int length, int id, ref int tag );
² JAVA_未测试
调用JAVA类,摘:http://zht1933.iteye.com/blog/607263
//Java源代码:
package com.zht; //c#中调用的类名
//要调用的Java类
public class Test
{ //要调用的Java方法
public String returnString()
{ return "Hello, zht!"; }
}
一、将已经编译后的java中Class文件进行打包;打包命令JAR
如:将某目录下的所有class文件夹全部进行打包处理;
使用的命令:jar cvf test.jar -C com/ .
其中test.jar为要生成的jar包;com/ . 为指定的当前目录下的文件夹,该文件夹包括子文件夹及class文件;
二、到IKVM官方网站下载IKVM需要的组件 http://www.ikvm.net/ (或http://sourceforge.net/projects/ikvm/files/)
a. kvm-0.42.0.3.zip
b. ikvmbin-0.42.0.3.zip
c. openjdk6-b16-stripped.zip
http://hi.baidu.com/chen_claire/blog/item/0efbd1101971d205b8127b0f.html 文中提到 b\c中Zip没有使用到。
三、设置路径
解压ikvm-0.42.0.3.zip,并将%IKVM_HOME%\bin添加到path中。此处的%IKVM_HOME%是指解压后ikvm的主目录。
四、将java的jar包转换为.dll控件
使用的命令:ikvmc -out:IKVM.dll test.jar
其中IKVM.dll为将要生成的.dll控件文件名;test.jar为之前打包好的jar包文件。
五、在C#项目中添加所需的控件
1、新建一个C#.NET项目,首先添加一下必须的DLLs
%IKVM_HOME%\bin\IKVM.OpenJDK.Core.dll
%IKVM_HOME%\bin\IKVM.Runtime.dll
%IKVM_HOME%\bin\IKVM.Runtime.JNI.dll
2、添加已生成的.dll文件
将之前生成好的.dll文件加载到C#项目中
六、测试
在C#项目中使用java类,其方法同java。但对包的引用使用C#的语法using
using com.zht; //与JAVA中的类名一致
namespace KIVMTest{ public partial class Form1 : Form { public Form1() { InitializeComponent();} private void Form1_Load(object sender, EventArgs e) { Test t = new Test();
string str = t.returnString();
MessageBox.Show(str); } }}
² JAVA_WebService
曾写与外公司的程序做过一次数据接口工作,当时那家公司提供了一个JAVA程序写的一个WebService
地址:http://10.176.32.186/epm/services/ImeterData?wsdl
方法://str xml格式的String类型
public int saveMeterReadingDate(String str,String appNo,String operSystem)
1、静态调用
先在项目中添加了一个WebService: WebReference.ImeterData
/// 调用服务 并发送 bool SendData ( List<string> lstr ){ int iReturn; bool bReturnSpecified; WebReference.ImeterData id = new DataProvider_MiddleDB.WebReference.ImeterData ( ); id.Url ="http://10.176.32.186/epm/services/ImeterData?wsdl" ; id.saveMeterReadingDate ( lstr [ 0 ] , sAppNo , operSystem ,
out iReturn , out bReturnSpecified );}
注:当时最大的问题是如何去取返回值,调用时发现有多个返回值。经过测试和网上查询,发现把返回值是写在方法参数内传入的。
2.动态调用(动态创建一个WebService)
public static object InvokeWebService ( string url , string classname , string methodname , object [ ] args ) { string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling"; #region 实例化服务 、调用服务方法 try { //获取WSDL WebClient wc = new WebClient ( ); url = url + "?wsdl"; //为从具有 System.String 指定的 URI 的资源下载的数据打开一个可读的流。 Stream stream = wc.OpenRead(url); //提供一种方法,以创建和格式化用于描述 XML Web services 的有效的 Web 服务描述语言 (WSDL) 文档文件, //该文件是完整的,具有适当的命名空间、元素和属性。无法继承此类。 ServiceDescription sd = ServiceDescription.Read ( stream ); //公开一种为 XML Web services 生成客户端代理类的方法。 ServiceDescriptionImporter sdi = new ServiceDescriptionImporter ( ); sdi.AddServiceDescription ( sd , "" , "" ); CodeNamespace cn = new CodeNamespace ( @namespace ); //生成客户端代理类代码 CodeCompileUnit ccu = new CodeCompileUnit ( ); ccu.Namespaces.Add ( cn ); sdi.Import ( cn , ccu ); CSharpCodeProvider csc = new CSharpCodeProvider ( ); ICodeCompiler icc = csc.CreateCompiler ( ); //设定编译参数 CompilerParameters cplist = new CompilerParameters ( ); cplist.GenerateExecutable = false; cplist.GenerateInMemory = true; cplist.ReferencedAssemblies.Add ( "System.dll" ); cplist.ReferencedAssemblies.Add ( "System.XML.dll" ); cplist.ReferencedAssemblies.Add ( "System.Web.Services.dll" ); cplist.ReferencedAssemblies.Add ( "System.Data.dll" ); //编译代理类 CompilerResults cr = icc.CompileAssemblyFromDom ( cplist , ccu ); if ( true == cr.Errors.HasErrors ) { System.Text.StringBuilder sb = new System.Text.StringBuilder ( ); foreach ( System.CodeDom.Compiler.CompilerError ce in cr.Errors ) { sb.Append ( ce.ToString ( ) ); sb.Append ( System.Environment.NewLine ); } throw new Exception ( sb.ToString ( ) ); } //生成代理实例,并调用方法 System.Reflection.Assembly assembly = cr.CompiledAssembly; Type t = assembly.GetType ( @namespace + "." + classname , true , true ); object obj = Activator.CreateInstance ( t ); System.Reflection.MethodInfo mi = t.GetMethod(methodname);// return mi.Invoke ( obj , args ); } catch ( Exception ex ) { throw new Exception ( ex.InnerException.Message , new Exception ( ex.InnerException.StackTrace ) ); } #endregion }
- 调用外部DLL,如:DelphiC++Java的DLL的调用方法,给出代码片段?
- LoadRunner调用外部DLL的方法
- vc++ 调用外部dll的方法
- DLL的调用方法
- QT调用dll、外部程序调用QT的dll.md
- java中调用dll的方法
- 关于Java调用dll的方法
- 关于Java调用dll的方法
- Java调用 dll 文件里的方法
- 关于Java调用dll的方法
- 关于Java调用dll的方法
- 关于Java调用dll的方法
- 关于Java调用dll的方法
- java 调用.net DLL的方法
- jni java调用win32 dll的方法
- java调用dll的几种方法
- java 调用.net DLL的方法
- java使用JNA调用dll的方法
- 根据NSArray里边的Object的某个属性进行排序
- 用Socket读取网页,但是经常出现错误
- strftime()函数详解
- PKU 3675 Telescope
- windows进程、线程和作业的基本了解
- 调用外部DLL,如:DelphiC++Java的DLL的调用方法,给出代码片段?
- 取得屏幕的宽高的问题
- buf 经典使用
- 解决出现的警告:Warning - secret file /etc/ppp/pap-secrets has world and/or group access Warning - secret fi
- [转] 80后的80条幽默有哲理的语录
- Linux中缺少so文件的问题
- c#中实现打印指定页(特定页), 附原代码
- WebLogic JDBC连接
- VS2008 C++ 调用MATLAB 2009b 生成的DLL