VC MFC DLL 代码文件
===========================[START]===============================
// testing.cpp : Defines the entry point for the DLL application.
//#include "stdafx.h"BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
 )
{
    return TRUE;
}extern "C" _declspec(dllexport) int Init()
{
return 0;
}extern "C" _declspec(dllexport) int ExecuteModule(int *t)
{
*t = 10;
return 5;
}
============================[END]================================DELPHI 调用方式
===========================[START]===============================
声明
var
  i,j,p,k,m: integer;调用
  k := 0;
  m := 0;
  p := 0;
  while p = 0 do
  begin
    j := ExecuteModule(i);
    k := k + 1;
    Application.ProcessMessages;
    If k = 1000000 then
    begin
      k := 0;
      m := m + 1;
      If m = 100000 then
      begin
p := 1;
      end;
    end;
  end;
============================[END]================================调用后程序内存开销越来越大,直到6000K就弹出"STACK OVERFLOW"的错误,
内存开销直到6232K, 6244K, 6220K, 6216K 等等。1. 为何内存开销增大?
2. 如何解决?

解决方案 »

  1.   

    由于Delphi中和VC中指定的调用约定不同,导致调用函数传入的参数未释放以至于堆栈溢出。全部改为stdcall方式看看
      

  2.   

    忘记写delphi下的函数声明  function Init(): integer; stdcall; external 'testing.dll';
      function ExecuteModule(var t: integer): integer; stdcall; external 'testing.dll';--------------------------
    to Eastunfail(龙子龙孙)==(恶鱼杀手)   vc下用stdcall方式声明的函数编译后的dll好像不能被delphi调用。
    vc下函数声明为
    extern "C" _stdcall int Init()
    extern "C" _stdcall int ExecuteModule(int *t)改为__stdcall好像也有问题。
      

  3.   

    我现在手上没有VC,我的VS.NET要等到晚上12点才能下完 :P
    明天帮你试试
      

  4.   

    工程和调用单元都要在uses的第一位置加上sharemem
      

  5.   

    TO soaringsouth(栈桥捉鳖) 程序运行没有问题,关闭程序时提示,Invalid pointer operation,不知道为何。
      

  6.   

    肯定是堆栈错误..................下VS.NET(7CD)下到57%结果没种了,郁闷
      

  7.   

    把ExecuteModule的定义帖出来看看
      

  8.   

    兄弟,两边的函数调用方式全部改成cdecl吧,我以前就遇到过这种情况,结果改成这种方式就全都解决了......
    其实最好的办法就是用vc做COM,然后用Delphi调用,这是我到目前位置研究到的最稳的办法了。
      

  9.   

    TO soaringsouth(栈桥捉鳖) 后来找到一个别人写的取代sharemem的东西,问题好像解决了,没有完全测试出结果。
    TO getit911(Windows转Linux中) 
    开始的时候ExecuteModule怎么写都有问题,就是简单的 加法运算,返回结果,返回值为操作是否成功仍在继续研究中...
      

  10.   

    function ExecuteModule(var t: integer): integer; stdcall;有问题吧,在C中是指针的参数啊
      

  11.   

    应该是参数的传递方式或者堆栈管理的方式不一样引起的
    这个即可:
    extern "C" __declspec(dllexport) __cdecl int ExecuteModule(int *t)
    {
    *t = 10;
    return 5;
    }
      

  12.   

    调用约定:
        __cdecl 缺省
          是 Borland C++ 的缺省的 C 格式命名约定,它在标识符前加一下划线,以保留
        它原来所有的全程标识符。参数按最右边参数优先的原则传递给栈,然后清栈。
            extaern "C" bool __cdecl TestFunction();
          在 def 文件中显示为 
            TestFunction @1
          注释: @1 表示函数的顺序数,将在“使用别名”时使用。    __pascal Pascal格式
          这时函数名全部变成大写,第一个参数先压栈,然后清栈。
            TESTFUNCTION @1 //def file    __stdcall 标准调用
          最后一个参数先压栈,然后清栈。
            TestFunction @1 //def file    __fastcall 把参数传递给寄存器
          第一个参数先压栈,然后清栈。
            @TestFunction @1 //def file
      

  13.   

    使用 stdcall 方式要这样修改:extern "C" __declspec(dllexport) __stdcall int ExecuteModule(int *t)同时在 VC 中增加 VC 工程 def 文件(你的为 testing.def)
    写下以下内容:
    EXPORTS
        ExecuteModule
      

  14.   

    测试一:
      Windows XP Prof
      VC++6, Win32DLL,声明方式为__stdcall。
      Delphi7, Application, 调用方式为stdcall。
      
      联调,启动后内存占用1336KB,运行函数后内存占用1352KB,5分钟内无改变,通过。
    以下是主要文件代码:0001TestDll.cpp
    ////////////////////////////////////////////////////////////////////////////
    // testing.cpp : Defines the entry point for the DLL application.
    //#include "stdafx.h"BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
     )
    {
        return TRUE;
    }extern "C" _declspec(dllexport) __stdcall int Init()
    {
    return 0;
    }extern "C" _declspec(dllexport) __stdcall int ExecuteModule(int *t, int *p)
    {
    *t = 10;
    *p = 11;
    return 5;
    }
    ////////////////////////////////////////////////////////////////////////////0001TestDll.Def
    ////////////////////////////////////////////////////////////////////////////
    EXPORTS
    Init @1
    ExecuteModule @2
    ////////////////////////////////////////////////////////////////////////////
    Unit1.pas
    ////////////////////////////////////////////////////////////////////////////
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        btnStart: TButton;
        btnStop: TButton;
        procedure btnStartClick(Sender: TObject);
        procedure btnStopClick(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;  function Init(): integer; stdcall; external '0001TestDll.Dll';
      function ExecuteModule(var t: integer; var p: integer): integer; stdcall; external '0001TestDll.dll';var
      Form1: TForm1;
      j: integer;implementation{$R *.dfm}procedure TForm1.btnStartClick(Sender: TObject);
    var
      t,p,r: integer;
    begin
      j := 1;
      Init();
      while j = 1 do
      begin
        r := ExecuteModule(t,p);
        Application.ProcessMessages;
      end;
    end;procedure TForm1.btnStopClick(Sender: TObject);
    begin
      j := 0;
    end;end.
    ////////////////////////////////////////////////////////////////////////////
    测试二:
      Windows XP Prof
      VC++6, Win32DLL,声明方式为__cdecl。
      Delphi7, Application, 调用方式为cdecl。
      
      联调,启动后内存占用1372KB,运行函数后内存占用1404KB,跳跃至1528KB,1532KB,5分钟内无改变,通过。
    总结:  (1)对于用Delphi调用VC++ DLL,
      方式1. VC++6采用 extern "C" _declspec(dllexport) __stdcall 方式声明函数, Delphi7采用stdcall方式调用;
      方式2. VC++6采用 extern "C" _declspec(dllexport) __cdecl 方式声明函数, Delphi7采用cdecl方式调用;  (2)如果工程和调用单元都要在uses的第一位置加上sharemem,内存占用更少。
      采用方式1,程序运行和退出时都没有问题,
      采用方式2,程序运行没有问题,关闭程序时提示,Invalid pointer operation错误。如果采用ShareMemRep.pas【Aimingoo ([email protected])】取代ShareMem就没有问题。  (3)如调用时采用索引号声明函数,可任意改变调用的函数名,如本例测试中
      function Init(): integer; stdcall; external '0001TestDll.Dll'; 可声明为
      function HardwareInit(): integer; stdcall; external '0001TestDll.Dll' index 1;  (4)__pascal关键字在VC++6中不被支持。 
      (5)采用__fastcall声明,采用register声明显示错误,不通过。
      

  15.   

    推荐采用stdcall + ShareMemRep方式。