CSDN的朋友们好,我遇到一个很着急的问题,希望你们能帮忙解决一下
我在VC++ 6.0 里声明的DLL函数如下
extern "C" _declspec(dllexport)  int _stdcall setValue(LPCSTR&  strtitle,LPCSTR&  strname,LPCSTR&  strvalue) ;
在VB 6.0里能够成功调用
导入格式如下:
Public Declare Function setValue Lib "setValue.dll" (ByRef strTitle As String, ByRef strName As String, ByRef strValue As String) As Integer
但在DELPHI 里用PChar实验了N次也没有成功
希望有人能帮忙解决一下
 谢谢了。在线等

解决方案 »

  1.   

    function setValue(var strtitle, strname, strvalue: PChar): Integer;
      

  2.   

    用PChar不行的啊。我实验了一下午了啊
      

  3.   

    function setValue(strtitle:PChar;strname:PChar;strvalue:PChar):integer;
    stdcall;external 'setValue.dll';
    这是我在DELPHI里的声明
    编译能够通过,但运行的时候,一到调用那里就出现内存错误
      

  4.   

    int _stdcall setValue(LPCSTR  &  strtitle,LPCSTR  &  strname,LPCSTR  &  strvalue) ;function setValue(var strtitle: PChar ;var strname: PChar ;var strvalue: PChar): Integer;试试。
      

  5.   

    那么为什么能用VB调用成功啊?
    不过,我现在可以肯定的是:绝对不是用PChar来解决的
      

  6.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Buttons;type
      TForm1 = class(TForm)
        BitBtn1: TBitBtn;
        Edit1: TEdit;
        procedure BitBtn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }  end;var
      Form1: TForm1;implementation{$R *.dfm}
    function setValue(var strtitle:PChar;var strname:PChar;var strvalue:PChar):integer;
    stdcall;external 'setValue.dll';procedure TForm1.BitBtn1Click(Sender: TObject);
    var
     resulta:integer;
     strtitle:PChar;
     strname:PChar;
     strvalue:PChar;
    begin
    strtitle:='个人客户信息';
    strname:='NAME';
    strvalue:='sadf';
    resulta:=setValue(strtitle,strname,strvalue);
    showmessage(inttostr(resulta));// 加上这句试试?
    end;end.
    这是全部的代码,怎么修改,参数也总是运行的时候,提示 "EAcessViolation" in module 'ole32.dll' 或kernel32.dll
      

  7.   

    注意,在vb和vc++下定义的string相当于delphi的widestring,而不是pchar
      

  8.   

    这样试试:procedure TForm1.BitBtn1Click(Sender: TObject);
    var
    resulta:integer;
    strtitle:PChar;
    strname:PChar;
    strvalue:PChar;
    begin
    strtitle := StrAlloc(256);
    strname := StrAlloc(256);
    strvalue := StrAlloc(256);
    StrCopy(strtitle, '个人客户信息');
    StrCopy(strname, 'NAME');
    StrCopy(strvalue, 'sadf');
    try
    resulta:=setValue(strtitle,strname,strvalue);
    finally
    StrDispose(strtitle);
    StrDispose(strvalue);
    StrDispose(strvalue);
    end;
    end;
      

  9.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Buttons;type
      TForm1 = class(TForm)
        BitBtn1: TBitBtn;
        Edit1: TEdit;
        procedure BitBtn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }  end;var
      Form1: TForm1;implementation{$R *.dfm}
    function setValue(strtitle:widestring;strname:widestring;strvalue:widestring):integer;
    stdcall;external 'setValue.dll';procedure TForm1.BitBtn1Click(Sender: TObject);
    var
     resulta:integer;
     strtitle:widestring;
     strname:widestring;
     strvalue:widestring;
    begin
    strtitle:='个人客户信息';
    strname:='NAME';
    strvalue:='sadf';
    resulta:=setValue(strtitle,strname,strvalue);
    showmessage(inttostr(resulta));// 加上这句试试?
    end;end.
    这是修改后的代码,还是不可以的啊
      

  10.   

    改成unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Buttons;type
      TForm1 = class(TForm)
        BitBtn1: TBitBtn;
        Edit1: TEdit;
        procedure BitBtn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }  end;var
      Form1: TForm1;implementation{$R *.dfm}
    function setValue(strtitle:PChar;strname:PChar;strvalue:PChar):integer;
    stdcall;external 'setValue.dll';procedure TForm1.BitBtn1Click(Sender: TObject);
    var
     resulta:integer;
     strtitle:PChar;
     strname:PChar;
     strvalue:PChar;
    begin
    //strtitle:='个人客户信息';
    //strname:='NAME';
    //strvalue:='sadf';
    strtitle := StrAlloc(256);
    strname := StrAlloc(256);
    strvalue := StrAlloc(256);
    StrCopy(strtitle, '个人客户信息');
    StrCopy(strname, 'NAME');
    StrCopy(strvalue, 'sadf');
    try
    resulta:=setValue(strtitle,strname,strvalue);
    finally
    StrDispose(strtitle);
    StrDispose(strvalue);
    StrDispose(strvalue);
    end;
    end;end.
    这样的了,还是不可以啊(有VAR没VAR都是错误的)
      

  11.   

    这是C++ DLL里的函数,大家帮忙看看有错误吗?
    如果有的话,在VB里怎么能成功调用呢?
    extern "C" _declspec(dllexport) int _stdcall setValue(LPCSTR&  strtitle,LPCSTR& strname,LPCSTR&  strvalue) 
    {
    CoInitialize(NULL);   
    SHDocVw::IShellWindowsPtr   m_spSHWinds;   
    if(m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows))   ==   S_OK)   
    {   
    IDispatchPtr   spDisp;   
    long   nCount   =   m_spSHWinds->GetCount();   
    for   (long   i   =   0;   i   <   nCount;   i++)   
    {   
    _variant_t   va(i,   VT_I4);   
    spDisp   =   m_spSHWinds->Item(va);   
    SHDocVw::IWebBrowser2Ptr   spBrowser(spDisp);   
    if   (spBrowser   !=   NULL)   
    {   
    IDispatchPtr   spDisp;   
    if(spBrowser->get_Document(&spDisp)   ==   S_OK   &&   spDisp!=   0   )   
    {   
    MSHTML::IHTMLDocument2Ptr   spHtmlDocument(spDisp);   
    MSHTML::IHTMLElementPtr   spHtmlElement;   
    if(spHtmlDocument==NULL)   
    continue; 
    CComBSTR bstrTitle;
    spHtmlDocument->get_title( &bstrTitle ); //取得文档标题
    printf(_bstr_t(bstrTitle)+"\n");  
    spHtmlDocument->get_body(&spHtmlElement);   
    if(spHtmlDocument==NULL)   
    continue;   
    HRESULT   hr;   
    MSHTML::IHTMLElementCollection*   pColl=NULL;   
    hr=spHtmlDocument->get_all(&pColl);   
    if(pColl!=NULL&&SUCCEEDED(hr))   
    {   
    long   lcount   =   0;   
    pColl->get_length(&lcount);
    for(int   i=0;i<lcount;i++)   
    {   
    _variant_t   index;   
    index.vt=VT_I4;   
    index.intVal=i;   
    IDispatchPtr   disp;   
    disp=pColl->item(index,index);
    if(disp==NULL)   
    hr=E_FAIL;   
    else   
    {   
    MSHTML::IHTMLInputElementPtr   pInput(disp);
    MSHTML::IHTMLSelectElementPtr pSelect(disp);
    if(pInput)   
    {   
    BSTR   bstrtype,bstrname;   
    pInput->get_type(&bstrtype);   
    printf(_bstr_t(bstrtype));
    pInput->get_name(&bstrname);
    if(StrCmpW(bstrTitle,_bstr_t(strtitle))==0)   
    {   
    if(StrCmpW(bstrtype,L"text")==0)
    {
    if(StrCmpW(bstrname,_bstr_t(strname))==0)
    {
    pInput->put_disabled(VARIANT_TRUE);
    pInput->put_readOnly(VARIANT_TRUE);
    pInput->put_value(_bstr_t(strvalue));   
    }
    }
    }
    SysFreeString(bstrtype);   
    }
    else if(pSelect)
    {
    BSTR bstrname;
    pSelect->get_name(&bstrname);
    if(StrCmpW(bstrname,_bstr_t(strname))==0)
    {
    if(StrCmpW(_bstr_t(strvalue),L"女")==0)
    {
    pSelect->selectedIndex=1;
    }
    pSelect->put_disabled(VARIANT_TRUE);
    }
    }
    }   

    }   
    pColl->Release();   
    }   
    }   

    }   
    }   

    }   
    else     
    {   
    printf("Shell   Windows   interface   is   not   avilable\n"); 
    return 1;
    }   
    CoUninitialize(); 
    return 0;
    return 0;
    }
      

  12.   

    type PPChar = ^PChar;再不行就没办法了。
      

  13.   

    function setValue(strtitle, strname, strvalue: PPChar): Integer;
      

  14.   

    你把setValue.dll和原码压缩成文件发到,我帮你看看先
      

  15.   

    代码已经解决了,第一次真正的知道了DELPHI调用C++ 变量类型可以不用改啊
    唉不过,还是谢谢各位了啊
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ActiveX, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1             : TForm1;implementationfunction setValue(var strtitle: LPCSTR; var strname: LPCSTR; var strvalue: LPCSTR): Integer; stdcall; external 'setValue.dll';{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
      res               : integer;
      a, b, c           : LPCSTR;
    begin
      a := '信贷管理';
      b := 'NAME';
      c := 'c';
      coinitialize(nil);
      res := setValue(a, b, c);
      ShowMessage(IntToStr(res));
      CoUninitialize;
    end;end.
      

  16.   

    没仔细看,你还可以定义成PAnsiChar;
      

  17.   

    简直匪夷所思
    LPCSTR = PAnsiChar;
    PChar = PAnsiChar;
      

  18.   

    extern "C" _declspec(dllexport)  int _stdcall setValue(LPCSTR&  strtitle,LPCSTR&  strname,LPCSTR&  strvalue) ;
    这样的东西delphi是无法调用的.
    因为这种LPCSTR&东西除了C++ 没其他语言支持.
    让VC的人再给你重做一份吧.用char**
      

  19.   

    几个字符串是用来存放返回值的, 但你根本没有分配空间!
    应该像下面的:procedure TForm1.BitBtn1Click(Sender: TObject);
    var
     resulta:integer;
     strtitle: array[0..255] of char;
     strname: array[0..256] of char;
     strvalue: array[0..256] of char;
    begin
    resulta:=setValue(@strtitle,@strname,@strvalue);
    end;
      

  20.   

    Windows.pas
      LPCSTR = PAnsiChar;
    system.pas
      PPChar        = ^PChar;
      PPAnsiChar    = PPChar;用PPChar看看。
      

  21.   

    我再说一遍,我贴出来的解决问题的代码,完全没有问题
    难道大家不知道在DELPHI里可以直接调用C++的dll吗?
    而不用来回转换变量的定义
    因为DELPHI已经全部将MFC集成进去了啊
    你们也太无知了吧
      

  22.   

    TO wead(π鹰)
    不要说别人无知,转换变量类型定义的目的是可读性,既然在DELPHI里面书写,就尽量使用DELPHI通用的类型。虽然集成MFC等定义,但那种定义对C开发者可能更适应,对PASCAL程序员来说,是很浪费时间的。
      

  23.   

    这样声明:extern   "C"   _declspec(dllexport)     int   _stdcall   setValue(LPCSTR     strtitle,LPCSTR     strname,LPCSTR     strvalue)
    参数不要传引用!