VB代码转Delphi代码,请熟悉两者的高手请进(一)

马行空牛耕田 2005-07-24 02:19:23
自我介绍: 本人是搞Java的,但现在有个windows平台的东东需要开发。其中有一部分已有代码是VB写的,现在要转成Delphi代码,此中过程本人因为两个开发语言/工具都不太熟悉,所以会有一些很基本的问题要问,希望大家不要介意,并且保持关注。 谢谢大家!

问题一:
外部dll函数声明:
VB代码如下:
Public Declare Function ReadMsg Lib "sample.dll" (ByVal IPort As Integer, ByRef CHMsg As Any, ByRef CHMsgLen As Long, ByRef PHMSg As Any, ByRef PHMsgLen As Long, ByVal iState As Integer) As Integer
相应的Delphi声明该如何呢?
我主要是不明白这个“ByRef CHMsg As Any”该怎么“翻译”,用万能指针? 请大虾给个例子

问题二:
VB有动态数组:
ReDim TmpData(1 To 16)
Delphi该怎么办? 请举个例子

问题三:
VB转换字符?
StrConv(TmpData, vbWide)
Delphi该怎么办? 请举个例子

有些问题我也知道可以通过查API去解决,但因为时间紧,没办法,有劳大虾了,100分不够我可以再另开帖子。请不要骂我懒,^_^

...全文
254 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
马行空牛耕田 2005-07-24
  • 打赏
  • 举报
回复
好吧,今天就到这了,结贴,明天再开新贴讨论转中文!
Eastunfail 2005-07-24
  • 打赏
  • 举报
回复
CopyMemory在Delphi中也能用
马行空牛耕田 2005-07-24
  • 打赏
  • 举报
回复
哦,问题1我明白了。

但是问题2还是乱码。

我看VB的TmpCHMsg(原始字符数组)的定义是:Dim TmpCHMsg(1 To 256) As Byte; 而Delphi中我的定义是:TmpCHMsg : array [1.. 256] of byte ; 这样匹配吗?

您可否用我1到30位打出来的信息“瀆魚eP ”,用你的程序作个测试?
Eastunfail 2005-07-24
  • 打赏
  • 举报
回复
写错了:
b := WideString(StrPas(PChar(DWORD(@TmpCHMsg)+31)));
Eastunfail 2005-07-24
  • 打赏
  • 举报
回复
b := WideString(StrPas(DWORD(@TmpCHMsg)+31));
马行空牛耕田 2005-07-24
  • 打赏
  • 举报
回复
To 多谢Eastunfail(龍子龍孫) (诚彼娘之非悦)
问题:
1、第31到50的信息怎么去取呢? 我是不是要把数组从中截取一下? 那么怎么截取呢?
2、这些信息都是中文的,需要转一下,我目前是这样做的:
var
b: widestring;
TmpCHMsg : array [1.. 256] of byte ;

TmpCHMsg[31] := $0; {先不管保存第31位的信息}
b := WideString(StrPas(@TmpCHMsg));

而VB里是这么实现的:
Dim TmpPos As Long
TmpPos = 0
ReDim TmpData(1 To 30) 'TmpData是个动态数组
CopyMemory TmpData(1), TmpCHMsg(1), 30
Label2.Caption = StrConv(TmpData, vbWide) '这个函数转化成双字节中文显示

我在我的Delphi程序中,1到30位打出来的信息是“瀆魚eP ”,怎么转都不行!
Eastunfail 2005-07-24
  • 打赏
  • 举报
回复
1)备份第31个字节
2)将第31设为0
3)获取byte数组指针
4)强制类型转换成PChar
5)StrPas函数转换为String
6)还原第31个字节内容
马行空牛耕田 2005-07-24
  • 打赏
  • 举报
回复
我痛苦死了,我都不好意思问了。
现在已知一个byte数组,我知道它前30位要取出来作个字符串(姓名),31到50位是另一个种信息,我怎么取啊。 Delphi的帮助好烦,我查了半天都不能直接查到对于Array的操作。我知道应该是System或者SysUtil unit中有,但是那么多Function,我真的不想去查啊,还是E文,faint!
Eastunfail 2005-07-24
  • 打赏
  • 举报
回复
hehe
马行空牛耕田 2005-07-24
  • 打赏
  • 举报
回复
To Eastunfail(龍子龍孫) (诚彼娘之非悦)
老大你真强,这都被你猜到了。

其实除了最开始和最后面的两个参数,其他的参数都应该是传地址的,所以我都给它加了var,就通过了。呵呵,多谢!
Eastunfail 2005-07-24
  • 打赏
  • 举报
回复
写错了:
Function ReadMsg(iPort : Integer; CHMsg:PChar;var CHMsgLen : Longint; PHMSg:PChar; var PHMsgLen : Longint; iState : Integer) : Integer; stdcall; external 'sample.dll';
Eastunfail 2005-07-24
  • 打赏
  • 举报
回复
哦~~~原来你是这样用的。那就把函数声明改成:
Function ReadMsg(iPort : Integer; CHMsg:PChar; CHMsgLen : Longint; PHMSg:PChar; PHMsgLen : Longint; iState : Integer) : Integer; stdcall; external 'sample.dll';
马行空牛耕田 2005-07-24
  • 打赏
  • 举报
回复
这个函数是从com1端口的一个硬件去读信息用的。 前面我也用了一些dll中的函数去从这个端口进行一些操作,都成功了,就这个不行!
马行空牛耕田 2005-07-24
  • 打赏
  • 举报
回复
函数声明:
Function ReadMsg(iPort : Integer; var CHMsg; CHMsgLen : Longint; var PHMSg; PHMsgLen : Longint; iState : Integer) : Integer; stdcall; external 'sample.dll';
这是变量定义:
iRet,PortFlag : Integer;
CardCHMsgLen, CardPHMsgLen : Longint;
TmpCHMsg, TmpPHMsg : PChar ;


这是调用时的代码:
iRet := ReadMsg(PortFlag, TmpCHMsg, CardCHMsgLen, TmpPHMsg, CardPHMsgLen, 1);

保证'sample.dll'中是有这个函数的,不过这是文档里说的,不知道什么工具可以查看dll中定义了哪些Function,呵呵
Eastunfail 2005-07-24
  • 打赏
  • 举报
回复
你怎么调用的?
把你调用函数所使用的变量声明贴出来
马行空牛耕田 2005-07-24
  • 打赏
  • 举报
回复
对于dll中的函数定义: ReadMsg (
int iPort,
unsigned char * pucCHMsg,
unsigned int * puiCHMsgLen,
unsigned char * pucPHMsg,
unsigned int * puiPHMsgLen,
int iIfOpen
);

我在Delphi中声明为:Function SDT_ReadBaseMsg (iPort : Integer; var CHMsg; CHMsgLen : Longint; var PHMSg; PHMsgLen : Longint; iState : Integer) : Integer; stdcall; external 'sample.dll';
调用的时候,我定义了
CardCHMsgLen, CardPHMsgLen : Longint;
TmpCHMsg, TmpPHMsg : PChar ;
作为它的参数,但是却报错了:
Project myproj.exe raised exception class EAccessViolation with message 'AccessViolation at address 1000185C in module 'sample.dll'.Write of address 77D32C4C '。。。. 这是怎么回事呢?  前面我也定义了类似的函数(来自sample.dll),也用了PChar,都成功了啊,为什么独独这个会报错呢? 怎么查呢?
redlegend_126_com 2005-07-24
  • 打赏
  • 举报
回复
?问题一:
?我主要是不明白这个“ByRef CHMsg As Any”该怎么“翻译”,用万能指针? 请大虾给个例子

var CHMsg就可以了!

?问题二:
VB有动态数组:
ReDim TmpData(1 To 16)
Delphi该怎么办? 请举个例子

var
pp:array of integer;
问题三:

VB转换字符?
StrConv(TmpData, vbWide)
Delphi该怎么办? 请举个例子

var
s: string;
b: widestring;
begin
s := 'Google';
b := s;

huiwww 2005-07-24
  • 打赏
  • 举报
回复
char,表示单个字符
PChar,类似与array of char,表示多个字符的字符串数组。
String,表示字符串,是物理地址下连续的字符串
马行空牛耕田 2005-07-24
  • 打赏
  • 举报
回复
成功,happy,多谢,不过我还是不理解Delphi的这个机制:
char,PChar,还有String,我都没搞清楚,唉!
TechnoFantasy 2005-07-24
  • 打赏
  • 举报
回复
可以用PChar
加载更多回复(5)

16,743

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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