测试Delphi DLL崩溃VB6 IDE [英] Testing Delphi DLL crashes VB6 IDE

查看:159
本文介绍了测试Delphi DLL崩溃VB6 IDE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我第一次去Delphi写一个DLL。到现在为止还挺好。通过使用typelib,我已经能够无障碍地将数据传入和传出DLL。



目前好奇的是我使用VB6作为测试台,并且每次在IDE中运行测试时,程序运行,然后IDE进程从内存中突然消失 - 没有错误消息,没有任何内容。如果我通过代码,一切正常,直到执行最后一行,然后IDE消失。



相比之下,当我将测试编译到EXE时,程序运行到最后,没有错误消息等。



有没有人有这个问题,有没有一个明显的解决方案,盯着我的脸?



下面的源代码,万一重要:



- 项目

 库BOSLAD; 

使用
ShareMem,
SysUtils,
Classes,
BOSLADCode in'BOSLADCode.pas';

出口
版本,
DMesg,
foo;
{$ R * .res}

begin
end。

- 单位

  unit BOSLADCode; 

界面
函数版本():Double; STDCALL;
程序DMesg(sText:WideString; sHead:WideString); STDCALL;
function foo():PWideString; STDCALL;

实现
使用Windows;

function version():Double;
var
s:String;
begin
result:= 0.001;
结束

程序DMesg(sText:WideString; sHead:WideString);
begin
Windows.MessageBoxW(0,PWideChar(sText),PWideChar(sHead),0);
结束

function foo():PWideString;
var s:WideString;
begin
s:='我的狗有跳蚤'
result:= PWideString(s);
结束
结束。

- typelib

  //这是BOSLAD.dll的类型库
[
//使用GUIDGEN.EXE创建唯一标识
的UUID //该用户的库系统。注意:这必须完成!
uuid(0C55D7DA-0840-40c0-B77C-DC72BE9D109E),
//这个helpstring定义了库将如何显示在VB的
//引用对话框中。
helpstring(BOSLAD TypeLib),
//假定标准英文语言环境。
lcid(0x0409),
//分配一个版本号来跟踪更改。
版本(1.0)
]
库BOSLAD
{

//现在定义将声明您的C函数的模块。
[
helpstring(BOSLAD.DLL中的函数),
版本(1.0),
//在此处给出您的DLL的名称。
dllname(BOSLAD.dll)
]
模块BOSLADFunctions
{
[helpstring(version),entry(version)] void __stdcall version ([out,retval] double * res);
[helpstring(DMesg),entry(DMesg)] void __stdcall DMesg([in] BSTR msg,[in] BSTR head);
[helpstring(foo),entry(foo)] void __stdcall foo([out,retval] BSTR * msg);
} //模块结束
}; //结束图书馆






我移动了在我声明它的函数之外的WideString,期望这会将变量的生命期延长到比 foo 函数的生命周期更长。它没有任何区别。



同样,我从VB6中注释到 foo 函数的调用。这也没有区别。无论我做什么,VB6 IDE在执行最后一行代码后都会死机。



除了指向局部变量的指针之外,还有一些原因是原因。但是什么?

解决方案

详细说明GSerg的答案:

  result:= PWideString(s); 

你会认为这是可以的,因为s被初始化了一个字符串文字...但是宽Delphi中的字符串不是像普通字符串一样被引用,所以实际上拥有一些动态分配的堆内存,一旦函数返回这个内存就可以重用:(



以下内容应该是可以的:

  function foo():PWideString; 
const s:WideString ='我的狗有跳蚤;
开始
结果:= PWideString(s);
结束;


I've had my first go at writing a DLL in Delphi. So far so good. By using a typelib I've been able to pass Widestrings to and from the DLL without difficulty.

What's curious at the moment is that I'm using VB6 as the testbed, and every time I run a test within the IDE, the program runs and then the IDE process suddenly disappears from memory - no error messages, nothing. If I step through the code, everything works fine until I execute the last line, then the IDE disappears.

By contrast, when I compile the test to an EXE the program runs to its end, without error messages etc.

Has anyone had this problem before and is there an obvious solution that's staring me in the face?

Source code below, in case it matters:

-- project

library BOSLAD;

uses
  ShareMem,
  SysUtils,
  Classes,
  BOSLADCode in 'BOSLADCode.pas';

exports
  version,
  DMesg,
  foo;
{$R *.res}

begin
end.

-- unit

unit BOSLADCode;

interface
  function version() : Double; stdcall;
  procedure DMesg(sText : WideString; sHead : WideString ); stdcall;
  function foo() : PWideString; stdcall;

implementation
  uses Windows;

  function version() : Double;
  var
    s : String;
  begin
    result := 0.001;
  end;

  procedure DMesg( sText : WideString; sHead : WideString);
  begin
    Windows.MessageBoxW(0, PWideChar(sText), PWideChar(sHead), 0);
  end;

  function foo() : PWideString;
  var s : WideString;
  begin
    s := 'My dog''s got fleas';
    result := PWideString(s);
  end;
end.

-- typelib

 // This is the type library for BOSLAD.dll
      [
      // Use GUIDGEN.EXE to create the UUID that uniquely identifies
      // this library on the user's system. NOTE: This must be done!!
         uuid(0C55D7DA-0840-40c0-B77C-DC72BE9D109E),
      // This helpstring defines how the library will appear in the
      // References dialog of VB.
         helpstring("BOSLAD TypeLib"),
      // Assume standard English locale.
         lcid(0x0409),
      // Assign a version number to keep track of changes.
         version(1.0)
      ]
      library BOSLAD
      {

      // Now define the module that will "declare" your C functions.
      [
         helpstring("Functions in BOSLAD.DLL"),
         version(1.0),
      // Give the name of your DLL here.
         dllname("BOSLAD.dll")
      ]
      module BOSLADFunctions
      {
[helpstring("version"), entry("version")] void __stdcall version( [out,retval] double* res );
[helpstring("DMesg"), entry("DMesg")] void __stdcall DMesg( [in] BSTR msg, [in] BSTR head );
[helpstring("foo"), entry("foo")] void __stdcall foo( [out,retval] BSTR* msg );
      } // End of Module
      }; // End of Library


I moved the declaration of the WideString outside of the function in which I had declared it, in the expectation that that would increase the lifetime of the variable to longer than just the lifetime of the foo function. It made no difference whatsoever.

Likewise I commented out of the VB6 the call to the foo function. That made no difference either. No matter what I do, VB6 IDE dies after the last line of code is executed.

Something apart from pointers to local variables is the cause. But what?

解决方案

To elaborate on GSerg's answer:

result := PWideString(s);

you'd think it would be ok because s was initialized with a string literal... but wide strings in Delphi are not reference counted like normal strings, so s actually holds a bit of dynamically allocated heap memory, and as soon as the function returns this memory can be reused :(

The following should be ok though:

function foo() : PWideString;
const s : WideString = 'My dog''s got fleas';
begin
  result := PWideString(s);
end;

这篇关于测试Delphi DLL崩溃VB6 IDE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆