delphi 写的dll 接口译成对应的C#,导入接口时 如何写!(100分)

  • 主题发起人 主题发起人 zmxk
  • 开始时间 开始时间
Z

zmxk

Unregistered / Unconfirmed
GUEST, unregistred user!
//delphi写的 demo.dll
//以下这个function功能输入userid及密码认证成功后就返回他的会员id号。
function Login(out MemberId: PChar;User_Id: PChar;
Password :PChar):Integer;stdcall;
begin
MemberId := PChar(MemberInfo.MemberId);//返回相应的会员ID
end;

//C#可以这样导入吗
[DllImport("demo.dll")] public static extern int Login(ref char[] MemberId, char[] User_Id, char[] Password);
//我这样调用在C#里
char[] userid = textBox1.Text.ToCharArray();
char[] memberid = new char[20];
int n = Login(ref memberid,userid,userid);
//处理的“System.Runtime.InteropServices.MarshalDirectiveException”类型的异常出现在 Demo.exe 中。
//其他信息: 无法封送 parameter #1:Ansi 字符数组不能作为 byref 或作为非托管到托管的参数进行封送处理。
 
PChar在C#中对应的类型用StringBuilder
 
在C#中调用Windows API
C#代码处于托管状态下工作,所以有完善的内存回收管理、类型安全性。但有时候,你想应用你以前在VC/Delphi下编写的非托管代码,C#同样也提供了这种Windows API调用支持,比如System.Win32名字空间下就是通过调用操作系统原有API的,以下我以“在VC中使用Delphi构造公共对话框”中的一个密码认证对话框的调用为例,说明如果在C#中调用系统标准的API函数。
首先我们来看CommonDlg.dll的API接口声明:
function ShowLoginDlg(hHandle: HWND;
szUser: PChar;
szPassword: PChar
): Integer;
stdcall;
要在C#中调用这个API,必须先声明该非托管API的接口:
using System;
using System.Text;
using System.Runtime.InteropServices;

namespace FormTest
{
/**//// <summary>
/// CommonDlgAPI 的摘要说明。
/// </summary>
public class CommonDlgAPI
{
public CommonDlgAPI()
{
//
// TODO: 在此处添加构造函数逻辑
//
}

[DllImport("CommonDlg.dll", CharSet = CharSet.Ansi)]
public static extern int ShowLoginDlg(int hHandle, StringBuilder szUser, StringBuilder szPassword);
}
} 然后用如下的C#代码来调用该接口:
private void buttonLogin_Click(object sender, System.EventArgs e)
{
StringBuilder szUser = new StringBuilder(32);
StringBuilder szPasswd = new StringBuilder(32);

if (CommonDlgAPI.ShowLoginDlg(0, szUser, szPasswd) == 1)
{
MessageBox.Show(szUser.ToString() + "/" + szPasswd.ToString());
}
}
显然,[DllImport("CommonDlg.dll", CharSet = CharSet.Ansi)]是整个声明的关键,这里声明一个导入API所在动态库的文件名为CommonDlg.dll,参数传递为ANSI类似的,如果的Unicode类形的API,则设置为CharSet.Unicode。
 
to xiammy
1//写个单向传输的例子(C#调用者只向dll aip传入参数值,不需要回传新值)
//delphi原型
function Login(User_Id: PChar;
Password :PChar):Integer;stdcall;
//C#导入
[DllImport("demo.dll")] public static extern int Login(char[] User_Id, char[] Password);
textBox1.Text = "ahzhang";
char[] userid = textBox1.Text.ToCharArray();
//call login
Login(userid,userid);
//在dll中获得的值是正确的。
function Login(User_Id: PChar;
Password :PChar):Integer;stdcall;
begin
showmessage(strpas(User_Id));//显示:ahzhang
showmessage(strpas(Password));//显示:ahzhang
end;

//我将C#导入改成这样就行了。如下
[DllImport("demo.dll")] public static extern int Login(out StringBuilder MemberId, char[] User_Id, char[] Password);
private void button1_Click(object sender, System.EventArgs e)
{

StringBuilder szmemberid = new StringBuilder(32);

char[] userid = textBox1.Text.ToCharArray();

int n = Crm_Login(out szmemberid,userid,userid);
switch(n)
{
case 0://Fail
MessageBox.Show("network connect Fail!");
break;
case 1://success
MessageBox.Show("Success!");
MessageBox.Show(szmemberid.ToString());
break;
//这里已经可以取回我需要的会员ID号了。
case 2:
MessageBox.Show("auth Fail!");
break;
case 3:
MessageBox.Show("Load Data Error!");
break;
default:
MessageBox.Show("other error!");
break;
}
有些疑问。做出来了,但有些事情搞得不是很清楚。
PChar是字符指针.指向字符串的首地址。
而StringBuilder与char[],有什么区别呢?
还有Char[]传递进去的是字符数组的首地址吧?用char[] 对应PChar参数类型定义 与 用StringBuilder 对应PChar参数类型定义有何区别呢?
请回复谢谢。。
结贴发分了。
 
后退
顶部