This Code is copied directly from the website commitcrm.com It is a demostration on how to use their API ( Like Hello World, it connects to an database, creates an account, and update that account )
It compiles perfect on Windows XP + Delphi 2007 and the executable works perfect.
If the exact same code is compiled on Windows 7 + Delphi XE2/XE5/XE7 then executable gives error :(
I have found that it is somehow related to Char / Ansichar, pChar / PAnsiChar.
Because, when I change the char to ansichar for the CmtInitDbEngDll procedure, it actually connect to the database. Great.
But I am not able to (I am not good enough) find out what I have to change...should it be char, ansichar, pchar, pansichar and so on, because I am not sure how to handle it when a DLL is involved.
Is there any smart delphi people who can help ?
------ SOURCE CODE ----------------------------------------------------
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.