Re: [fpc-pascal] Cannot find entry point of a routine inside a windows 64 dll
Sven Barth via fpc-pascal wrote: On 15.12.2017 16:10, Dennis wrote: Okay, that explains things a bit more. May I ask you to provide a small example consisting of program and library (source only) that works in 32-bit, but fails in 64-bit? Try way I can check myself what is going on as I have a Delphi starter on my 64-bit Windows as well. Though it will be the weekend till I'll have the time to look at it. Sven, Attached is a zipped file containing the Caller program and Callee dll. Both Compiled ok in windows 32 but when running Caller.exe, it reported the error. Thanks a lot. There were two adjustments I had to do to make it work correctly: - add {$mode objfpc} to Caller.lpr as I was compiling from the commandline - adjust the casing of ReOpenExcelWorkBook so that it matched the one from ReopenExcelWorkBook (these are case sensitive!) With these changes it worked without problem on win64. That said you might want to apply the following two points to your library interface: - export/import functions/procedures using explicit names (extending "external LibName" to "external LibName name 'ProcName'" for each routine to import and adding "name 'ProcName'" for each routine in the exports section) to be sure that no name mangling interferes here - add an explicit calling convention to each routine for import and export (you could use "register", the default calling convention since Delphi and FPC *should* be compatible here, but "stdcall" would be my suggestion to be on the save side) Additionally you can check for any discrepancies using the Dependency Walker ( http://www.dependencywalker.com/ ). Just open the executable while the library is located in the same directory and you can see which routines mismatch. Regards, Sven Thank you so much!!! Dennis ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Cannot find entry point of a routine inside a windows 64 dll
On 15.12.2017 16:10, Dennis wrote: >> >> Okay, that explains things a bit more. >> >> May I ask you to provide a small example consisting of program and >> library (source only) that works in 32-bit, but fails in 64-bit? Try >> way I can check myself what is going on as I have a Delphi starter on >> my 64-bit Windows as well. Though it will be the weekend till I'll >> have the time to look at it. > > Sven, > > Attached is a zipped file containing the Caller program and Callee dll. > Both Compiled ok in windows 32 but when running Caller.exe, it reported > the error. > > Thanks a lot. There were two adjustments I had to do to make it work correctly: - add {$mode objfpc} to Caller.lpr as I was compiling from the commandline - adjust the casing of ReOpenExcelWorkBook so that it matched the one from ReopenExcelWorkBook (these are case sensitive!) With these changes it worked without problem on win64. That said you might want to apply the following two points to your library interface: - export/import functions/procedures using explicit names (extending "external LibName" to "external LibName name 'ProcName'" for each routine to import and adding "name 'ProcName'" for each routine in the exports section) to be sure that no name mangling interferes here - add an explicit calling convention to each routine for import and export (you could use "register", the default calling convention since Delphi and FPC *should* be compatible here, but "stdcall" would be my suggestion to be on the save side) Additionally you can check for any discrepancies using the Dependency Walker ( http://www.dependencywalker.com/ ). Just open the executable while the library is located in the same directory and you can see which routines mismatch. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Cannot find entry point of a routine inside a windows 64 dll
Am 13.12.2017 18:13 schrieb "Dennis": Sven Barth via fpc-pascal wrote: > Am 13.12.2017 11:39 schrieb "Dennis Poon" >: > > > > Just for clarification: is the excel_xp.dll written by you or by a 3rd > party? Or are you talking about a different library written by you? Because > in the latter case the interfacing choice between your program and *that* > library nicht be the culprit. > > Let me explain. My program is a 32 bit program that collects real time stock prices and group the prices by each minute into Open, High, Low, Close, Volume of that minute. The program needs to add these rows of open,high,lose,close,volume in real-time to an opened Excel Spreadsheet (that the end users will write his own VBA formula to manipulate the rows I add). To do so, I need to use Microsoft OLE Automation but I don't know how to do it in Lazarus. But there is a component in Delphi that uses OLE Automation to update an excel spreadsheet, so I wrote my own excel_xp.dll in Delphi to use that TExcelApplication component (from Delphi) which is then called by my 32-bit lazarus program. Everything worked in 32-bit. Since there is no FREE 64-bit Delphi IDE available, before I purchase a 64-Bit delphi, I need to make sure my Lazarus program can compile to 64 bit windows program and can call a 64-bit windows DLL so I use Lazarus 64 bit to write a stub 64-bit windows dll to be called by my 64-bit Lazarus program. However, on running, it complained "Cannot find entry point of a routine ", which never happened when everything was 32-bit. My question is why the exact routine definitions worked in 32-bit but did not work in 64 bit. Okay, that explains things a bit more. May I ask you to provide a small example consisting of program and library (source only) that works in 32-bit, but fails in 64-bit? Try way I can check myself what is going on as I have a Delphi starter on my 64-bit Windows as well. Though it will be the weekend till I'll have the time to look at it. Someone might asked why I did not compile the TExcelApplication directly in Lazarus to do without the linked dll. I tried, it just won't compile and the task of translating the huge source files from Delphi to FPC is too daunting. What kind of errors did you face? Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Cannot find entry point of a routine inside a windows 64 dll
Sven Barth via fpc-pascal wrote: Am 13.12.2017 11:39 schrieb "Dennis Poon">: Just for clarification: is the excel_xp.dll written by you or by a 3rd party? Or are you talking about a different library written by you? Because in the latter case the interfacing choice between your program and *that* library nicht be the culprit. Let me explain. My program is a 32 bit program that collects real time stock prices and group the prices by each minute into Open, High, Low, Close, Volume of that minute. The program needs to add these rows of open,high,lose,close,volume in real-time to an opened Excel Spreadsheet (that the end users will write his own VBA formula to manipulate the rows I add). To do so, I need to use Microsoft OLE Automation but I don't know how to do it in Lazarus. But there is a component in Delphi that uses OLE Automation to update an excel spreadsheet, so I wrote my own excel_xp.dll in Delphi to use that TExcelApplication component (from Delphi) which is then called by my 32-bit lazarus program. Everything worked in 32-bit. Since there is no FREE 64-bit Delphi IDE available, before I purchase a 64-Bit delphi, I need to make sure my Lazarus program can compile to 64 bit windows program and can call a 64-bit windows DLL so I use Lazarus 64 bit to write a stub 64-bit windows dll to be called by my 64-bit Lazarus program. However, on running, it complained "Cannot find entry point of a routine ", which never happened when everything was 32-bit. My question is why the exact routine definitions worked in 32-bit but did not work in 64 bit. Someone might asked why I did not compile the TExcelApplication directly in Lazarus to do without the linked dll. I tried, it just won't compile and the task of translating the huge source files from Delphi to FPC is too daunting. Dennis ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Cannot find entry point of a routine inside a windows 64 dll
Am 13.12.2017 11:39 schrieb "Dennis Poon": Sven Barth via fpc-pascal wrote: Am 13.12.2017 03:04 schrieb "Dennis" >: > > I am converting my windows 32 program to 64 bit. > It compiled with lazarus without any problem.(fpc 3.0.2) > > I also compile the dll that is used, into a 64 bit dll. > > However, when I ran the 64 bit program, windows reported 'cannot > find the entry point "the routine name in the dll" (the dll file name) > > In the routine of the dll, there is an out parameter of type > WideString, > > could this be the problem? > > If not, what else could be the cause of the problem? > > > Considering the code you gave I really wonder how that ever worked... Did > you set the calling convention using the $calling directive? Otherwise you > need to add it to every function. Also you're on the eager side by using > the "name" clause for the external as you can be sure then what name is > used. Lastly are you sure that the DLL you're dealing with is a 64-bit > library? > > In the original 32 bit program, I wrote the windows 32-bit dll in the Starter (FREE) edition of Delphi and call (using those codes I showed you) from my FPC 32 bit program without any problem. Since there is NO FREE Delphi for 64 bit version, I wrote a windows 64-bit program using FPC 64 bit and then try calling it from my FPC 64-bit program and encountered the "Cannot find entry point of a routine inside a windows 64 dll" error. Just for clarification: is the excel_xp.dll written by you or by a 3rd party? Or are you talking about a different library written by you? Because in the latter case the interfacing choice between your program and *that* library nicht be the culprit. In the 32 bit program, I did not use the $calling directive and did not use 'name' clause and it worked perfectly. I could add the name clause in the 64 bit program, but can you teach me how to use the $calling directive? Since in the 64 bit version, i will be writing both the dll and the calling program, what $calling directive should I use? Do I need to specify it clearly on both the dll and the calling code? Perhaps before we go to this you should first explain a bit more how the structure of your application looks like (regarding libraries), cause currently I'm kinda confused. Maybe you should take a look at fpSpreadsheet which allows you to work with > Excel files of different versions directly and does not need a library. > > I tried to use the fpSpreadsheet sample program last time. If the 64 bit dll thing did not work out, I will have to rely on the fpSpreadsheet thing but my customers are all used to Excel and prefer sticking to it :-( Are you trying to interact with a love running Excel instance? In that case I agree. However if your trying to modify Excel files that are currently closed then it shouldn't matter whether you use fpSpreadsheet. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Cannot find entry point of a routine inside a windows 64 dll
Sven Barth via fpc-pascal wrote: Am 13.12.2017 03:04 schrieb "Dennis">: I am converting my windows 32 program to 64 bit. It compiled with lazarus without any problem.(fpc 3.0.2) I also compile the dll that is used, into a 64 bit dll. However, when I ran the 64 bit program, windows reported 'cannot find the entry point "the routine name in the dll" (the dll file name) In the routine of the dll, there is an out parameter of type WideString, could this be the problem? If not, what else could be the cause of the problem? Considering the code you gave I really wonder how that ever worked... Did you set the calling convention using the $calling directive? Otherwise you need to add it to every function. Also you're on the eager side by using the "name" clause for the external as you can be sure then what name is used. Lastly are you sure that the DLL you're dealing with is a 64-bit library? In the original 32 bit program, I wrote the windows 32-bit dll in the Starter (FREE) edition of Delphi and call (using those codes I showed you) from my FPC 32 bit program without any problem. Since there is NO FREE Delphi for 64 bit version, I wrote a windows 64-bit program using FPC 64 bit and then try calling it from my FPC 64-bit program and encountered the "Cannot find entry point of a routine inside a windows 64 dll" error. In the 32 bit program, I did not use the $calling directive and did not use 'name' clause and it worked perfectly. I could add the name clause in the 64 bit program, but can you teach me how to use the $calling directive? Since in the 64 bit version, i will be writing both the dll and the calling program, what $calling directive should I use? Do I need to specify it clearly on both the dll and the calling code? Maybe you should take a look at fpSpreadsheet which allows you to work with Excel files of different versions directly and does not need a library. I tried to use the fpSpreadsheet sample program last time. If the 64 bit dll thing did not work out, I will have to rely on the fpSpreadsheet thing but my customers are all used to Excel and prefer sticking to it :-( Thanks for your response. Dennis Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Cannot find entry point of a routine inside a windows 64 dll
Am 13.12.2017 03:04 schrieb "Dennis": I am converting my windows 32 program to 64 bit. It compiled with lazarus without any problem.(fpc 3.0.2) I also compile the dll that is used, into a 64 bit dll. However, when I ran the 64 bit program, windows reported 'cannot find the entry point "the routine name in the dll" (the dll file name) In the routine of the dll, there is an out parameter of type WideString, could this be the problem? If not, what else could be the cause of the problem? Considering the code you gave I really wonder how that ever worked... Did you set the calling convention using the $calling directive? Otherwise you need to add it to every function. Also you're on the eager side by using the "name" clause for the external as you can be sure then what name is used. Lastly are you sure that the DLL you're dealing with is a 64-bit library? Maybe you should take a look at fpSpreadsheet which allows you to work with Excel files of different versions directly and does not need a library. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
[fpc-pascal] Cannot find entry point of a routine inside a windows 64 dll
I am converting my windows 32 program to 64 bit. It compiled with lazarus without any problem.(fpc 3.0.2) I also compile the dll that is used, into a 64 bit dll. However, when I ran the 64 bit program, windows reported 'cannot find the entry point "the routine name in the dll" (the dll file name) In the routine of the dll, there is an out parameter of type WideString, could this be the problem? If not, what else could be the cause of the problem? Below is the calling program: Dennis - const ExcelDLLName = 'Excel_xp.dll';//1.90951 Type TFileNameString = WideString;//1.90951 TExcelErrorString = WideString;//1.90952 TExcelValueString = WideString;//1.90952 EExcel_OLE=class(Exception); EExcel_OLE_Rejected=class(EExcel_OLE); EExcel_OLE_Rejected_ToWrite = class(EExcel_OLE_Rejected); procedure Excel_Finalize;external ExcelDLLName name 'Finalize'; procedure ResetExcelOLE(out TheError: TExcelErrorString);external ExcelDLLName;//1.90967 //1.90952 function OpenWorkBook(TheFileName : TFileNameString; out TheErrorIdx : integer) : integer;external ExcelDLLName; //1.90952 function OpenWorkSheet(const TheWorkBook : integer; const TheSheetName : TFileNameString; out TheErrorIdx : integer) : integer;external ExcelDLLName; //1.90952 procedure WriteToCell(const TheWorkSheet : integer; const TheRow, TheCol : integer; TheValue : String);external ExcelDLLName; //1.90952 function WriteToRange(const TheSheetIndex : integer;TheRow, StartCol: integer; TheValues: array of variant; IsSkipIfNoChange: Boolean ) : integer;external ExcelDLLName;//used internally procedure WriteToExcelRow(const TheSheetIndex: integer; TheRow, StartCol: integer; TheValues: array of Variant; out TheError: TExcelErrorString);external ExcelDLLName;//used internally procedure WriteRow(const TheSheetIndex : integer;TheRow, StartCol: integer; TheValues: array of variant; var TheError : TExcelErrorString);external ExcelDLLName;//used internally //1.90952 function GetCellValue(const TheWorkSheetIndex : integer; const TheRow, TheCol : integer) : Variant;external ExcelDLLName; function GetCellVariant(const TheWorkSheetIndex : integer; const TheRow, TheCol : integer; var TheError : TExcelErrorString) : Variant;external ExcelDLLName; function IsRangeNull(const TheSheetIndex : integer;const TheRow, StartCol, TheRowCount, TheColCount : integer; var TheError : TExcelErrorString) : Boolean;external ExcelDLLName; function GetExcelRange(const TheWorkSheetIndex: integer; const TheRow, TheCol, TheRowCount, TheColCount: integer; var TheError: TExcelErrorString): variant; external ExcelDLLName; function OpenExcelWorkBook(TheFileName: TFileNameString; out TheError: TExcelErrorString): integer;external ExcelDLLName; function OpenExcelWorkSheet(const TheWorkBook: integer; const TheSheetName: TFileNameString; out TheError: TExcelErrorString): integer;external ExcelDLLName; procedure WriteToExcelRange(const TheSheetIndex: integer; TheRow, StartCol: integer; TheValues: Variant; out TheError: TExcelErrorString);external ExcelDLLName; procedure ReOpenExcelWorkSheet(TheWorkSheetIndex : integer; out TheError : TExcelErrorString);external ExcelDLLName;//1.90966 procedure ReOpenExcelWorkBook(TheWorkBookIndex : integer; out TheError : TExcelErrorString);external ExcelDLLName;//1.90966 procedure SaveAllExcelWorkBooks(out TheError : TExcelErrorString);external ExcelDLLName;//1.90967 procedure SaveExcelWorkBook(TheBookIndex : integer; out TheError: TExcelErrorString);external ExcelDLLName;//1.91495 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal