Char,AnsiChar,PChar,PAnsiChar?

时间:2015-03-30 18:13:12

标签: delphi dll char

此代码直接从网站commitcrm.com复制 这是关于如何使用他们的API(如Hello World,连接到数据库,创建帐户,更新该帐户的说明)

它在Windows XP + Delphi 2007上编译完美,可执行文件完美

如果在Windows 7 + Delphi XE2 / XE5 / XE7上编译完全相同的代码,则可执行文件会出错:(

我发现它与Char / Ansichar,pChar / PAnsiChar在某种程度上相关

因为,当我更改 CmtInitDbEngDll过程的ansichar时,它实际连接到数据库。大。

但是我不能(我不够好)找出我要改变的东西......应该是char,ansichar,pchar,pansichar等等,因为我不知道如何处理它涉及DLL。

有没有聪明的德尔福人可以提供帮助?

------消息来源--------------------------------------- -------------

program Demo;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes;

const
 C_DataBuffSize = 1024;
 C_MapBufSize = 1024;
 C_ErrMsgBuffSize = 1024;
 C_DescSize = 1024;
 C_ErrCodeBuffSize = 64;
 C_RecIDBuffSize = 64;

 C_Flag = 1;
 C_Ok = 1;
 C_AccountsTable = 10;
 C_AppName = 'Demo';

 CmtDbEngDll = 'C:\CommitCRM\ThirdParty\UserDev\CmtDbEng.DLL';

var
 Status: integer;
 DataBuff: array [0..C_DataBuffSize] of Char;
 MapBuff: array [0..C_MapBufSize] of Char;
 RecIdBuff: array [0..C_RecIDBuffSize] of Char;
 ErrCodesBuff: array [0..C_ErrCodeBuffSize] of Char;
 ErrMsgBuff: array [0..C_ErrMsgBuffSize] of Char;
 s: string;

//** Establishing connection with CommitCRM, Should be called only once for the entire session *
Procedure CmtInitDbEngDll (
             xSoftWareName   : PChar; // Your application name. Once selected this  string
                                      // will be used for all
                                      // functions of the package. Specify a meaningful value.
             xDbPath         : PChar; // Path to the DB folder under where CommitCRM server is
                                      // installed <server>\CommitCRM\Db

             var xvStatus     : integer           // Returned connection status
            ); stdcall; external CmtDbEngDll;

//**** Insert/Update record
Procedure CmtInsUpdRec(
             xSoftWareName   : pChar;            // See above
             xDataKind           : integer;      // Desired Table Code
             xDataBuff           : pChar;        // String containing the values, which we want
                                                 // to add into the Database
             xMapBuff            : pChar;        // List of the database fields into
                                                 //which we want to add data
             xContWhenInvalidData : Integer;     //Flag - stop(0)/continue(1) the input process
                                                 // is some data value(s) is invalid
             xFlags                : Integer;              // Not used
             xRecIDBuffLen      : Integer;          // Length of REC ID Buffer
             xLogErrCodesBuffLen  : Integer;  // Length of Error Code Buffer
             xLogErrMsgBuffLen     : Integer;     // Length of Error Message Buffer
             xvRecIDBuff          : pChar;            // Buffer for returned REC ID
             xvErrCodesLogBuff : pChar;         // Buffer for returned Error Codes
             xvErrMsgLogBuff    : pChar;         // Buffer for returned Error Messages
              var xvStatus       : Integer          // Returned status
             ); stdcall; external CmtDbEngDll;

//**** Terminate connection with CommitCRM ****
procedure CmtTerminateDbEngDll; stdcall; external CmtDbEngDll;

procedure CmtGetDescriptionByCode(
                                 xCode     : Integer;
                                 xDescLen  : Integer;
                                 xvDesc    : pChar); stdcall; external CmtDbEngDll;

procedure CmtGetDescriptionByStatus(
                                   xCode     : Integer;
                                   xDescLen  : Integer;
                                   xvDesc    : pChar); stdcall; external CmtDbEngDll;

procedure ErrCodesParsing (ErrCodeBuff: string);
var
 lList: TStringList;
 i: integer;
 aDescErrCode : Pchar;
begin
 try
   lList := TStringList.Create;
   lList.Text := ErrCodeBuff;
   GetMem(aDescErrCode,C_DescSize);
   for i := 0 to lList.Count - 1 do
   begin
     CmtGetDescriptionByCode(StrToInt(lList[i]), C_DescSize, aDescErrCode);
     writeln('Error Code: '+lList[i]+' Desc: '+string(aDescErrCode));
   end;
 finally
   FreeMem(aDescErrCode);
   lList.Destroy;
 end;
end;

procedure DisplayErrStatusCode(xCode : Integer);
var
 aStatusErrCode : Pchar;
begin
 try
   GetMem(aStatusErrCode,C_DescSize);
   CmtGetDescriptionByStatus(xCode,C_DescSize, aStatusErrCode);
   writeln('Commit Init failed. Error code: '+Inttostr(xCode)+' Desc: '+string(aStatusErrCode));
 finally
   FreeMem(aStatusErrCode);
 end;
end;

begin

 //**** Establishing connection with CommitCRM, Should be called only once for the entire session
 CmtInitDbEngDll(C_AppName, // Your application name. Once selected this string will be used
                            // for all functions of the package. Specify a meaningful value.
  'C:\CommitCRM\Db\',                    // Path to the DB folder under where CommitCRM server is
                                          // installed <server>\CommitCRM\Db
  Status                   // Returned connection status
   );

 if Status = C_Ok then
 begin

   //**** Insert a new Account into the Accounts table ****

   s := '"Bart De Hantsetters","De Hantsetters","Hantsetters"';
   StrPCopy(DataBuff, s);
   s := '"'+#13','+#13+'FLDCRDFULLNAME'+#13+'FLDCRDDEAR'+#13+'FLDCRDCONTACT'+#0;
   StrPCopy(MapBuff, s);

    CmtInsUpdRec(C_AppName,         // Your application name
                 C_AccountsTable,   // Desired Table Code
                 DataBuff,          // String containing the values, which we want to add into
                                    // the Database
                 MapBuff,           // List of the Database Fields in which we want to add data
                 C_Flag,            // Flag - stop(0)/continue(1) the input process is some data
                                    // value(s) is invalid
                 0,                             // Not used
                 C_RecIDBuffSize,         // Llength of REC ID Buffer
                 C_ErrCodeBuffSize,      // Length of Error Code Buffer
                 C_ErrMsgBuffSize,       // Length of Error Message Buffer
                 RecIdBuff,                 // Buffer for returned REC ID
                 ErrCodesBuff,             // Buffer for returned Error Codes
                 ErrMsgBuff,                // Buffer for returned Error Messages
                 Status                      // Returned status
         );



   if (ErrMsgBuff[0] <> #0) then
     writeln('Error Message: '+ ErrMsgBuff);

   ErrCodesParsing(ErrCodesBuff);

   if Status = C_Ok then
   begin
 //**** Updating the Account record we've just created *****

     // Map file for the update transaction - the Dear field and the record id
     s := '"'+#13+','+#13+'FLDCRDDEAR'+#13'FLDCRDRECID';
     StrPCopy(MapBuff, s);

     s := '"Doctor","'+RecIdBuff+'"';
     StrPCopy(DataBuff, s);

     CmtInsUpdRec(C_AppName,           // Your application name
                  C_AccountsTable,     // Desired Table Code
                  DataBuff,            // String containing  the values, which we want
                                       // to add into the Database
                  MapBuff,             // List of the database fields into which we want to add
                                       //data
                  C_Flag,              // Flag - stop(0)/continue(1) the input process is some
                                       // data value(s) is invalid
                  0,                   // Not used
                  C_RecIDBuffSize,     // Length of REC ID Buffer
                  C_ErrCodeBuffSize,   // Length of Error Code Buffer
                  C_ErrMsgBuffSize,    // Length of Error Message Buffer
                  RecIdBuff,           // Buffer for returned RECID
                  ErrCodesBuff,        // Buffer for returned Error Codes
                  ErrMsgBuff,          // Buffer for returned Error Messages
                  Status               // Returned status
         );

     if ((ErrMsgBuff[0] <> #0)) then
       writeln('Error Message: '+ ErrMsgBuff);

     ErrCodesParsing(ErrCodesBuff);

     if Status = C_Ok then
       Writeln('Completed Successfully');
   end
   else
   begin
     try
       s := IntToStr(Status);
     except
       s := 'ill-defined';
     end;
     writeln('Insert new Account. Error code: '+ s);
   end;

 //**** Terminate connection with CommitCRM****

   CmtTerminateDbEngDll();
 end
 else
 begin
   DisplayErrStatusCode(Status);
 end;

 writeln(#13#10+'press Enter to quit');
 readln;
end.

1 个答案:

答案 0 :(得分:1)

Delphi直到并包括Delphi 2007基本上都是8位ANSI。 Delphi 2009及更高版本是Unicode。

以下是两个可能有用的链接:

  

Embarcadero在RAD Studio中引入了完整的Unicode支持   八月的第一次   在这样做的过程中,他们确保Delphi和C ++ Builder始终处于Wind的本机应用程序开发的最前沿   ows平台将在很长一段时间内到来。

     

然而,与许多人不同   Delphi中引入的其他主要增强功能   年,如变体和接口(Delphi 3),框架(Delphi 5),   函数内联和嵌套类(Delphi 2005)和泛型(RAD   Studio 2009),启用Unicode并不涉及简单地添加新的   Delphi中已经支持的功能。相反,它参与其中   对几种基本数据类型的彻底改变   几乎每个Delphi应用程序。具体来说,定义为   字符串,字符和PChar类型已更改。

     

未采纳这些更改   轻轻。相反,他们只是在广泛之后才被引入   考虑这些变化可能带来的影响   现有的应用程序以及它们将如何影响未来   发展。此外,Embarcadero寻求投入和建议   许多支持和推广Delphi的技术合作伙伴。

     

实际上,没有办法实现Unicode支持   一些不便。   ...

     

String类型现在由UnicodeString类型定义,它是一个   UTF-16字符串。同样,Char类型现在是WideChar,一个两字节   字符类型,PChar是PWideChar,指向两个字节的指针   炭。

     

关于这些基本数据类型更改的重点是   至少,每个字符至少由一个代码表示   单位(两个字节),有时更多。