Since everybody and his brother is talking about the new chat engine from openapi I had to try it myself, and lo and behold it is amazing. I asked it about various topics and the answers I got were at least plausible. Being a Delphi developer I of course ended up asking it questions about Delphi and even learned some things I didn’t know. But the truly amazing part was when I asked about using the Turbo-JPEG library from Delphi. I not only gave me the code for loading the DLL, declaring and using the functions in it but when afterwards asked
Is there a more object oriented way to dynamically load a dll and and use it?
It gave me the following answer:
Yes, you can use the LoadLibrary and GetProcAddress functions to dynamically load a DLL and access its functions and procedures in an object-oriented way by defining a class or interface that represents the DLL and its functions and procedures.
Here is an example of how you might define a class to represent the TurboJPEG library and its functions:
type TTurboJpeg = class private hLib: HMODULE; tjInitDecompress: tjInitDecompress; tjDecompressHeader3: tjDecompressHeader3; tjDecompress2: tjDecompress2; tjDestroy: tjDestroy; public constructor Create; destructor Destroy; override; function InitDecompress(srcBuf: Pointer; const size: Cardinal): tjhandle; function DecompressHeader3(handle: tjhandle; srcBuf: Pointer; const size: Cardinal; width: PCardinal; height: PCardinal; jpegSubsamp: PInteger): Integer; function Decompress2(handle: tjhandle; srcBuf: Pointer; const size: Cardinal; dstBuf: Pointer; width: Cardinal; pitch: Cardinal; height: Cardinal; pixelFormat: Integer; flags: Integer): Integer; procedure Destroy(handle: tjhandle); end; constructor TTurboJpeg.Create; begin inherited Create; hLib := LoadLibrary(TurboJpegDLL); if hLib = 0 then raise Exception.CreateFmt('Error loading %s', [TurboJpegDLL]); tjInitDecomp // somehow the code that should go here is missing. It probably should use GetProcAddress to initialize the tj* fields of the class. function TTurboJpeg.InitDecompress(srcBuf: Pointer; const size: Cardinal): tjhandle; begin Result := tjInitDecompress(srcBuf, size); end; function TTurboJpeg.DecompressHeader3(handle: tjhandle; srcBuf: Pointer; const size: Cardinal; width: PCardinal; height: PCardinal; jpegSubsamp: PInteger): Integer; begin Result := tjDecompressHeader3(handle, srcBuf, size, width, height, jpegSubsamp); end; function TTurboJpeg.Decompress2(handle: tjhandle; srcBuf: Pointer; const size: Cardinal; dstBuf: Pointer; width: Cardinal; pitch: Cardinal; height: Cardinal; pixelFormat: Integer; flags: Integer): Integer; begin Result := tjDecompress2(handle, srcBuf, size, dstBuf, width, pitch, height, pixelFormat, flags); end; procedure TTurboJpeg.Destroy(handle: tjhandle); begin tjDestroy(handle); end; destructor TTurboJpeg.Destroy; begin if hLib <> 0 then FreeLibrary(hLib); inherited Destroy; end;
This looks a lot like the class I had written myself in code that is not freely available on the Internet, so I wonder where it got this from. Of course it won’t even compile because the field names of the class are the same as the type declarations for the imported functions and there are probably other bugs in there too.
There were other oddities too:
E.g. it claimed that GExperts has some functionality to extract procedures from code which it clearly does not have (I should know) but which are already part of the Delphi IDE.
Or it used SizeOf() of a pointer to a buffer where it should have passed the size of the buffer rather than that of the pointer.
So, I’d definitely not simply use any code it generates, but it might help a lot by providing some boilerplate code that takes a lot of time to generate but is boring to write.
Overall I was really impressed.