有这样两个C++的接口
EXPORT int GetDoorStatus(int col,char* info);EXPORT unsigned char* GetVuquestData();小弟没做过接C++这种接口的。
网上说用String/byte[]/StringBuilder接的,我都尝试一下,不知道是没写对还是怎么地,总是直接崩溃退出连错都不报希望有大神根据上边俩接口来一段简单明了的Demo
EXPORT int GetDoorStatus(int col,char* info);EXPORT unsigned char* GetVuquestData();小弟没做过接C++这种接口的。
网上说用String/byte[]/StringBuilder接的,我都尝试一下,不知道是没写对还是怎么地,总是直接崩溃退出连错都不报希望有大神根据上边俩接口来一段简单明了的Demo
解决方案 »
- App_Code 类调用 *.aspx.cs
- 帮忙解决立即给100分!如何把document.getElementById(a)保存到数据库 并读取
- C#中textBox的pressKey事件后保留textBox的值
- 一个正则表达式的替换问题,将URL批次替换为JS方法……
- c# 急……… 关于背景颜色问题!有图
- 对象锁定的问题.........如何得知对象是否锁定
- 感谢liujia 及其他朋友的帮助,俺做的项目成为国内第一家顺利通过微软PCT测试的项目
- 将控件参数保存到XML后,如何取出并设置到控件内?
- 表名怎么传进去?
- C# 往SqlServer插入null值
- 关于.net中如何使产生的对象不被回收
- 求指点
[DllImport("zhilaiBox.dll", CallingConvention = CallingConvention.Cdecl)] /// <summary>
/// 测试
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnGetDoorStatus_Click(object sender, EventArgs e)
{
string txt = "test";
IntPtr info = Marshal.StringToHGlobalAnsi(txt);
GetDoorStatus(int.Parse(txtColId.Text), info);
string strInfo = Marshal.PtrToStringAnsi(info);
WriteLog((sender as Button).Text, strInfo.ToString());
}
我发现我这么做倒是可以打出来LOG,但是打出来LOG之后就卡死直接崩掉退出了,这是为什么
[DllImport("zhilaiBox.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int GetDoorStatus(int col, IntPtr p);
谁使用谁申请谁释放
所以调用时,不能按照c#的套路,只定义,不申请资源
具体来说,
char* info要返回,需要使用stringbuilder来对应
而stringbuilder需要new时分配空间
分配大小要根据api的文件来定,和返回对象的大小相关
比如,使用 StringBuilder test = new StringBuilder();
那么肯定会引发崩溃,因为c传回的地方只有指针而没有对应的空间
StringBuilder test = new StringBuilder(40);
这样就可以了
2. DllImport的时候,凡涉及char*,就需要说明 CharSet
c/c++大多数默认是Ansi,而C#默认是Unicode,
大小不一致,会因为访问越界导致崩溃
IntPtr GetVuquestData();
我还记得这种调用必须设置.net framework 3.5 CPU设置为x86才行的,.net版本设置4.0以上或者cpu选择x64、anycpu就会报错误。 [DllImport("SerialExtDll.dll", EntryPoint = "GetNCDataList_AV131", CallingConvention = CallingConvention.Cdecl)]
private static extern int GetNCDataList_AV131(ref byte sendMsg); public string GetNCDataList_AV131()
{
string result = null;
try
{
byte[] sendData = new byte[256];
GetNCDataList_AV131(ref sendData[0]);
int length = 0;
for (int i = 0; i < 256; ++i)//去掉指令后面的空字符
{
if (sendData[i] == 0x00)
{
length = i;
break;
}
}
result = System.Text.Encoding.UTF8.GetString(sendData, 0, length);
result = result.ToUpper();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return result;
}
extern "C" SERIALEXTDLL_API int _stdcall GetNCDataList_AV131(char* sendCode)
{
byte byteNext[] = { 0x02, 0x30, 0x33, 0x43, 0x31, 0x54, 0x44, 0x35, 0x03 };// 这里是c++写的dll
char tempCode[256];//
memset(tempCode,0,sizeof(tempCode)); for(int i =0; i<sizeof(byteNext); ++i)
{
sprintf(tempCode,"%c",byteNext[i]);
strcat(sendCode,tempCode);
}
return 0;
}