Calling Clarion From Python
February 03, 2006
In my blog post Getting Jiggy with Clarion and Python, I discussed the Python oriented aspects of calling an external windows .DLL. Specifically I advocated the use of the ctypes module. This module makes the effort of dynamically linking to a .DLL nearly trivial. Continuing from my article on A Clarion Export Template, my task was to create a command-line utility for exporting some Topspeed files in Clarion to a ‘~’ delimited text file. Once I created the template and the basic program in Clarion, I had to figure out how to make it into a true command-line utility. I’m definitely not an expert in C (it’s been quite a few years since college now) so that pretty much ruled that out. And I wanted to try D but that seemed a little too much like C for something I wanted to get done in one day (although I may go back and try to redo the calling program in D at some point). So that left me with Python using ctypes.
My Python program is here:
import sys from ctypes import * def exportFile(tableName,outputFileName): wd = windll.LoadLibrary('exportfi.dll') cTableName = create_string_buffer(tableName,10) cOutputFileName = create_string_buffer(outputFileName,255) expcon = wd.EXPORTCONTROLLER expcon.restype = c_byte return expcon(cTableName,cOutputFileName) if __name__ == '__main__': if len(sys.argv) != 3: print "usage: exportfi tablename exportfilename" else: exportFile(sys.argv[1],sys.argv[2])
This part is fairly straight forward — looking at the exportFile function:
- My Clarion .DLL is loaded is loaded
- New c (pointer-based) string buffers have to be created to hold the contents of the the Python variables
- The function is identified and assigned to a local Python variable (for convenience)
- The function’s return type is set as a c_byte
- The return value for the function is then returned from the function call
The main Python code is the standard stuff for actually running things. It verifies that the right number of parameters were passed in and then it calls the Python function.
The trickier part is really the Clarion code. To make it more portable, I chose it to compile as seen here:

The truly important part here is that it has to be a 32-bit application. The “Local” indicates that I want all the Clarion .DLL’s used compiled into the final .DLL output. And of course you need to select that you want to output as a .DLL rather than an .EXE.
For this particular application, I only want to export one function in the .DLL called ExportController. This function setup looks like this in the IDE:

You’ll notice that the “Export Procedure” check box is checked, but also (and you can’t quite see it all), I specified a special prototype.
(LONG,LONG),BYTE,PASCAL
The PASCAL part is important since it specifies the calling method and PASCAL is the standard convention for Windows .DLL’s. The parameters I just have listed as LONG’s because I’m going to need to convert the pointers into CSTRINGS after they get passed in.
The real keys to success then are found inside the function itself…
FileToConvert CSTRING(20) ExportName CSTRING(255) CODE ! Begin processed code lstrcpy(ADDRESS(FileToConvert),lptrTable) lstrcpy(ADDRESS(ExportName),lptrExport)
What we then have are useable variables in Clarion and we can proceed as normal. I should note that in order to call the Windows API lstrcpy function you need the following declaration in your GLOBAL MAP:
MODULE('Windows.DLL')
lstrcpy(LONG,LONG),LONG,PASCAL,RAW,NAME('lstrcpyA')
ENDThe observant Clarion expert will notice that this is actually a bit of the lazy way out of this. I didn’t bother to import the Windows API EQUATES and I instead just defined the parameters as LONG’s for the API call (since essentially that’s what they EQUATE to).
That’s about it. You should be able to then call a Clarion .DLL from Python. And using the Clarion portion of this article, you should be able to able prep your DLL for really being called by any external language since what was done here is not specific to dealing with Python but rather just exporting a function in a standardized Windows .DLL sort of way. Enjoy!
No comments yet. Be the first.
Leave a reply