C#程序调用DLL中的非托管函数的问题

wangchangming 2009-04-19 12:10:30
C#如何调用dll里面的extern "C" int _stdcall db_encrypt(char *in, char *out, int size);

是[DllImport("data_api.dll")]
public static extern int db_encrypt(out char input,out char output,int size)还是
public static extern int db_encrypt(string input,string output,int size)?
对C++不熟.
...全文
126 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangchangming 2009-04-21
  • 打赏
  • 举报
回复

[DllImport("data_api.dll",CharSet = CharSet.Ansi)]
static extern int db_encrypt(StringBuilder input, StringBuilder output, int size);

[DllImport("data_api.dll",CharSet =CharSet.Ansi)]
static extern int db_decrypt(StringBuilder input, StringBuilder output, int size);
解决了!
gomoku 2009-04-20
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 wangchangming 的回复:]
...
我再调试C++
CString str="no";
...
[/Quote]

这是由于你的C++项目默认用了_UNICODE或UNICODE预编译定义。
由于这时候CString内部用的是宽字符,str用ASCII字符初始化后,内部缓冲区实际为'n' '\0' 'o' '\0' '\0' '\0'
你用GetBuffer()返回的缓冲区,加上str.GetLength的2,实际上是加密'n''\0'这两个字节。这当然跟加密"no"不一样了。
wangchangming 2009-04-20
  • 打赏
  • 举报
回复
多谢楼上的,我用
[DllImport("data_api.dll")]
public static extern int db_encrypt(byte[] input,byte[] output,int size);

private btn_click(sender,e)
{
byte[] input=System.Text.Encoding.UTF8.GetBytes("no");
byte[] output=new byte[2550];
db_encrypt(input,output,input.Length);
string s=new string(System.Encoding.UTF8.GetChars(output));
MessageBox.Show(s);
}
//输出:E8C26A4967A24757

我再调试C++
CString str="no";
char o[2550];
for(int i=0;i<=2550;j++)
{
o[i]='0';
}
db_encrypt(str.GetBuffer(1),o,str.GetLength());
//这里o为:9E54E0A97D3A4744
我改用
db_encrypt("no",o,2)
//则o输出来的跟C#里面的一致:E8C26A4967A24757
实际o为:9E54E0A97D3A4744,所以C#里面的E8C26A4967A24757是不对的。
C++的GetBuffer()是什么意思,(我用LPTSTR p=str.GetBuffer(1)查看显示Name:p value:0X00dc381c "no")转换到C#该如何处理?
gomoku 2009-04-20
  • 打赏
  • 举报
回复
要学会怎么找到可能出错的地方,比如:

1、在C++中
byte* pBytes = str.GetBuffer();
然后设置断点,确认pBytes[0]==0x6E pBytes[1]==0x0

2、确认C#中string s=new string(System.Encoding.UTF8.GetChars(output))的转换方式,跟C++中的显示是兼容的。
wangchangming 2009-04-20
  • 打赏
  • 举报
回复
CString str="no";

那按照C++ db_encrypt(str.GetBuffer(1),o,str.GetLength())加密是对'n','\0'加密,而不是对"no"加密,
而C#下面是按"no"加密?
那C#下要对'n','\0'加密怎么写,我用

char[] c = new char[] { 'n','\0'};
byte[] input = System.Text.Encoding.UTF8.GetBytes(c);
byte[] output = new byte[2550];
db_encrypt(input, output, 2);
是C478A0C104C5D78F,也不是9E54E0A97D3A4744
周药师 2009-04-19
  • 打赏
  • 举报
回复
是 public static extern int db_encrypt(string input,string output,int size)
龙宜坡 2009-04-19
  • 打赏
  • 举报
回复
public static extern int db_encrypt(string input,string output,int size);
rtdb 2009-04-19
  • 打赏
  • 举报
回复
若是有编码问题,还可能是:
public static extern int db_encrypt(byte[] input, byte[] output,int size)
rtdb 2009-04-19
  • 打赏
  • 举报
回复
好象都不对。

char *in, char *out
感觉上一般第一个是输入,第二是输出,

所以请试一下:

public static extern int db_encrypt(string input, [Out]StringBuilder output,int size)
help1120 2009-04-19
  • 打赏
  • 举报
回复
学习!!!
gomoku 2009-04-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 gomoku 的回复:]
public static extern int db_encrypt(string input,StringBuilder output,int size);
string的默认封送方向是[In],而StringBuilder为[In, Out]。因而你可以用StringBuilder来接收输出(注意StringBuilder要先分配足够的空间)。
[/Quote]

如果输入输入不是字符串的话,用db_encrypt(byte[] input, byte[] output, int size);
gomoku 2009-04-19
  • 打赏
  • 举报
回复
public static extern int db_encrypt(string input,StringBuilder output,int size);


string的默认封送方向是[In],而StringBuilder为[In, Out]。因而你可以用StringBuilder来接收输出(注意StringBuilder要先分配足够的空间)。
shanshiofrain 2009-04-19
  • 打赏
  • 举报
回复
前两个参数是指针啊,在C#里面也要专门的对应指针的类型,
li45214521 2009-04-19
  • 打赏
  • 举报
回复
public static extern int db_encrypt([MarshalAs(UnmanagedType.LPStr)]string input,([MarshalAs(UnmanagedType.LPStr)]string output,int size);
蓝海D鱼 2009-04-19
  • 打赏
  • 举报
回复

public static extern int db_encrypt(char[] input,char[] output,int size)
xufzu123 2009-04-19
  • 打赏
  • 举报
回复
public static extern int db_encrypt(char[] input,char[] output,int size)
这样好像行~

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧