to guanxuegong:
肯定不是这种问题,LPTSTR 在非 Unicode 的版本中就等于 char *,那只不过是一个宏而已。
肯定不是这种问题,LPTSTR 在非 Unicode 的版本中就等于 char *,那只不过是一个宏而已。
解决方案 »
- 各位仁兄请帮助我一下!!
- 初学,请问怎样在TreeView中显示数据库的数据
- 有关数据集简单问题,急!!!!!!!!!
- 如何判断ValueListEditor控件中哪一行被选择?
- 我建了一个链,最后想释放它,该怎么做?是不是用dispose()。distpose是用在一个节点上的,还是可以用在整条链上.
- 怎样动态修改DBGRID中的各列的标题成中文?只有"SELECT F1 AS '中文' from table "的办法?
- 关于笔记本保存问题
- 急问:已知窗口的Handle,如何设定把焦点放到这个窗口上?
- 不显示删除回复显示所有回复显示星级回复显示得分回复 请教个indy10 idtelnet插件的问题~maxlineaction
- 关于用TQuery实现多表关联查询的问题
- 有关改变数据库记录顺序的问题
- 如何在Delphi中实现类似VB中的控件数组?
PChar(...)可以把String型转成PChar型,具体实现方案是
建立一个Buffer,和这个String一样长,然后返回这个Buffer的首地址,首地址为32比特
例如PChar('abcde')的值可能等于$00450F03
PChar(...)可以把Integer或Char型转成PChar型,具体实现方案是
直接把这个整数或字符转成32比特的指针型
例如PChar(65535)=$0000FFFF,PChar('2')=$00000032所以,传入参数PChar('a')当然不行了。应该改为
var
c:char;
begin
c:='a';
CFunc(@c);
end;
一定可以
问题是我在delphi 中调用时,该参数既可能是一个字符的字符串,也可能是多个字符的字符串。所以当前我的代码是这个样子的:var
s: string;
...
// assigns value to s here, 'a' or 'abc'
...
// then:
fxn(PChar(s));如何能最简单的解决这个问题?
当然加了,要不然怎么能其他的长度就正常。
~~~
你可以这样
fxn(PChar(String('Some chars')));
如果你先申明一个string的变量,
s:string;
s:='Some chars';
fxn(PChar(s));也可以。我不同意题外话:)
用C,C++,你更要注意不要让编译器产生歧义
Buffer: PChar;
begin
GetMem(Buffer, 1024);//你的字串长度
StrCopy(Buffer, 'some chars');
fxn(Buffer);
Freemem(Buffer);
end;
应该可以的,如果不行传指针过去试一下.
please mailto :[email protected]和我讨论
因此,这个问题的来源不一定是Delphi,而是C函数的内部实现没有处理这种明显的二异性。可以肯定的说,你用C程序以同样的内存布局去调用它,同样会出问题。所以解决方法很简单,明确定义char*的实际含义,目标内存区域是字符还是字串,如果是字串,一个字符的字串,同样按两个字节的内存占用处理,就不会出现任何问题。这也是为什么API定义中引入LPCZSTR宏的原因之一。
To: <JGTM2000>> 您好,
> 首先为您能关注我的问题致谢。
> 您的考虑有一定的正确之处,但好像和我的问题不能吻合。
> 我为了验证这一问题,曾经专门另外做了一个DLL,输出的函数里面只有一行代码,就是将delphi中传入的参数原封不动的传入到MessageBox函数里,结果照样出错。您知道,MessageBox函数是必然会将该值作为字符缓冲区的首址。
> 相反的,我不动我的DLL,把delphi中对我DLL的输出函数原型中的参数类型由PChar改为Integer,调用的时候用Integer(@StrBuffer)的形式传入到DLL中,执行结果完全正常。
> 由此推断,错误必然发生在delphi上,而不是我的DLL。能否将您所说的相关代码贴来?根据我的判断,PChar和Integer不是重要的,因为那是对编译器而言的概念,只要在内存中的地址和布局一致,结果一定是一样的,无论用谁来写。我想搞清楚一个问题,就是您如何能够判断传入的指针的目标内存区到底是一个字符还是一个字串?从Delphi的角度讲,无论多长的字串内存布局都是一样的,即字串本身内容+ASCIIZ(对于array [0..x] of char, PChar(AnsiString), string const)。
顺便再问一下,为什么在 Delphi 的集成环境中不能调试对 Oracle 数据有操作的程序?无论是使用 ADO 还是其他控件我都能遇见这个问题。
sConst = 'a';
pcConst : PChar = 'a';
caConst0: array [0..0] of char = 'a'; // !!
caConst1: array [0..1] of char = 'a';
strConst: string = 'a';
cConst: char = 'a';
nullChar: char = #0;{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
begin
// asm int 3; end; // comment/uncomment this line to trigger breakpoint here
Windows.MessageBox(Handle,sConst,'Test',MB_OK);
Windows.MessageBox(Handle,pcConst,'Test',MB_OK);
Windows.MessageBox(Handle,caConst0,'Test',MB_OK); // cause incorrect tail
Windows.MessageBox(Handle,caConst1,'Test',MB_OK);
Windows.MessageBox(Handle,PChar(strConst),'Test',MB_OK);
Windows.MessageBox(Handle,@cConst,'Test',MB_OK); // cause incorrect tail
Windows.MessageBox(Handle,@nullChar,'Test',MB_OK);
Windows.MessageBox(Handle,nil,'Test',MB_OK);
end;什么情况编译和结果都正确,为什么那两句结果不正确,希望大家好好体会一下(最好在CPU窗口中研究一下内存布局,相信体会更深)。BTW, 评论一件产品(或一个人)的时候,最好先确保自己完全理解他,否则坏了人家的名声多冤呀。哈哈