接续帖http://topic.csdn.net/u/20100528/16/6ac8563f-54c3-492d-97ca-dee01c93073b.htm

chpst 2010-07-23 04:11:02
http://topic.csdn.net/u/20100528/16/6ac8563f-54c3-492d-97ca-dee01c93073b.html
那个问题绕过去了。我用delphi完成了工作,在c++build中仍没通过。但有点心不甘。在c#vs2008中都能过。
附代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

#region 定义调用Delphi写的DLL
///
/// 定义调用Delphi写的DLL
///
private class castnt
{
//定义DLL文件名,此文件路径要加到系统Path中
private const string _fileDll = @"castnt.dll";

[DllImport(_fileDll, EntryPoint = "OpenCommPort", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int OpenCommPort(int intProt);
[DllImport(_fileDll, EntryPoint = "CloseCommPort", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern string CloseCommPort();
[DllImport(_fileDll, EntryPoint = "ReadTime", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
//C#中的申明
// public static extern int ReadTime(int intDevno, ref byte[] strGet);
public static extern int ReadTime(int intDevno, ref StringBuilder strGet);

[DllImport(_fileDll, EntryPoint = "ReadTime", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]

public static extern int ReadVersion(int intDevno, ref StringBuilder strGet);
//function ReadVersion(intDevno: Integer; var strGet: Pchar): Integer; stdcall; external 'castnt.dll';

}
#endregion

private void button1_Click(object sender, EventArgs e)
{
int intOpen;
intOpen = castnt.OpenCommPort(4);
if (intOpen == 1)
MessageBox.Show("串口打开成功");
else
MessageBox.Show("串口打开失败");
}

private void button2_Click(object sender, EventArgs e)
{
int intReturn;
StringBuilder strGet;


strGet = new StringBuilder();
intReturn =castnt.ReadTime(1, ref strGet);
if (intReturn == 1)
{
//Rtb.Text = System.Text.Encoding.Default.GetString(strGet);
Rtb.Text = strGet.ToString();
MessageBox.Show("成功");

}
else

MessageBox.Show("失败");
}

private void button3_Click(object sender, EventArgs e)
{
int intReturn;
StringBuilder strGet;

strGet = new StringBuilder();
intReturn = castnt.ReadVersion(1, ref strGet);
if (intReturn == 1)
{

Rtb.Text = strGet.ToString();
MessageBox.Show("成功");

}
else

MessageBox.Show("失败");
}


//function OpenCommPort(intProt: Integer): Integer; stdcall; external 'castnt.dll';
//procedure CloseCommPort(); stdcall; external 'castnt.dll';
//function ReadTime(intDevno: Integer; var strGet: Pchar): Integer; stdcall; external 'castnt.dll'; //读取日期时间


}
}
太奇怪了。
我认为就是是传值那个参数没写对。大家有兴趣研究下。
...全文
242 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
chpst 2010-07-26
  • 打赏
  • 举报
回复
早上来一试就OK了,妖哥说得很明白了。内存泄漏我在观察下,真没注意呢。动态,静态调用都对了。结贴
周药师 2010-07-24
  • 打赏
  • 举报
回复
lz在C#没有问题
很大一个幸运的是 C#是托管了的 new了 不需要人工释放
ccrun.com 2010-07-24
  • 打赏
  • 举报
回复
原来楼主的问题还木有解决.

经过研究楼主前阵子发给我的Delphi Demo工程, 我在C++Builder中创建了一个Dll, 模拟ReadTime的函数实现, 经测试发现, ReadTime的第二个参数应该用指针的指针. 也就是:
typedef int (__stdcall *READTIME) (int intDevno, LPSTR *strGet);
void __fastcall TForm1::Button4Click(TObject *Sender)
{
HANDLE h = ::LoadLibrary(TEXT("castnt.dll"));
if (h)
{
READTIME ReadTime = (READTIME)::GetProcAddress(h, "ReadTime");
if (ReadTime)
{
LPSTR lpBuffer;
int intReturn = ReadTime(1, &lpBuffer);
if (intReturn == 1)
{
Memo1->Lines->Add(strGet);
}
}
::FreeLibrary(h);
}
}


猜测应该是在ReadTime函数的内部开辟了缓冲空间, 然后赋值.
但是现在有一个问题: 疑似有内存泄露啊. 开辟的缓冲在虾米地方释放了呢?
亮剑_ 2010-07-24
  • 打赏
  • 举报
回复
好多代码
Waiting4you 2010-07-23
  • 打赏
  • 举报
回复
直接试试这样,看看ReadTime会不会改变strGet的指针(也就是说它可能会帮我们申请一块内存输出来)。
  char *strGet = NULL;
int intReturn = ReadTime(1,strGet);

或者:
  typedef int (__stdcall *ReadTime) (int intDevno, LPSTR *strGet);

char *strGet = NULL;
int intReturn = ReadTime(1,&strGet);

周药师 2010-07-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 waiting4you 的回复:]
这个ref有点可疑,小试一下
typedef int (__stdcall *ReadTime) (int intDevno, LPSTR *strGet);

typedef int (__stdcall *ReadTime) (int intDevno, LPSTR &strGet);
[/Quote]
不按代码 格式贴代码 好乱 不想看

这个ref 是输出的意思

C++可以用引用输出
chpst 2010-07-23
  • 打赏
  • 举报
回复
我找了个可imlib 静态调用
castnt.h
extern "C" _stdcall int OpenCommPort(int intProt);
extern "C" _stdcall void CloseCommPort();
extern "C" _stdcall int ReadVersion(int intDevno, LPSTR & strGet);
extern "C" _stdcall int ReadTime(int intDevno, LPSTR & strGet);

调用代码

void __fastcall TForm1::Button1Click(TObject *Sender)
{
int a = OpenCommPort(4);
if (a==1)
ShowMessage("OK connect Serial 4.");
} //这个可以打开串口。
void __fastcall TForm1::Button3Click(TObject *Sender)
{
char strGet[256] = { 0 };
memset(strGet, 0, 256);

int intReturn = ReadTime(1,strGet);
if (intReturn == 1)
{
Memo1->Lines->Add(AnsiString(strGet));
Label1->Caption=AnsiString(strGet);
}
} //这个调用成功,输出为空。
Waiting4you 2010-07-23
  • 打赏
  • 举报
回复
这个ref有点可疑,小试一下
typedef int (__stdcall *ReadTime) (int intDevno, LPSTR *strGet);

typedef int (__stdcall *ReadTime) (int intDevno, LPSTR &strGet);

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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