On Oct 2, 2010, at 7:20 AM, Ken Thomases wrote:
>> Sorry to be obtuse, but it may be that I am overlooking something. 
>> Presently, we have calls such as
>> 
>> n = PyNumber_Float(obj)
>> s = PyString_AsString(obj)
>> 
>> I understand that I would need to generate #defines for all those names, 
>> such as PyNumber_Float to map them to some table. I would have to initialize 
>> that table in a big for loop that goes through another table containing the 
>> name of each function (e.g. "PyNumber_Float". The loop then looks each name 
>> up with dlsym and initializes the table.
>> 
>> Or can this be done more elegantly?
> Declare function pointers:
> 
> typeof(PyNumber_Float) *pPyNumber_Float;
> typeof(PyString_AsString) * pPyString_AsString;
> 
> This can be table-ized with a macro:
> 
> #define DOFUNC(f) typeof(f) *p##f
>       DOFUNC(PyNumber_Float);
>       DOFUNC(PyString_AsString);
>       // ...
> #undef DOFUNC
> 
> 
> During initialization, dynamically load the Python framework with dlopen().  
> Then, load the function pointers by looking up the symbols:
> 
> pPyNumber_Float = dlsym(handle, "PyNumber_Float");
> pPyString_AsString = dlsym(handle, "PyString_AsString");
> 
> This can be table-ized with a macro:
> 
> #define DOFUNC(f) do { if (!(p##f = dlsym(handle, #f))) { \
>       fprintf(stderr, "Failed to load %s\n", #f); \
>       goto bail; \
> } while (0)
>       DOFUNC(PyNumber_Float);
>       DOFUNC(PyString_AsString);
>       // ...
> #undef DOFUNC
> 
> 
> Notice that the table within the definitions of DOFUNC is identical in both 
> cases.  So, you can extract it to a separate file and #include it between the 
> DOFUNC #define and #undef:
> 
> #define DOFUNC(f) /* whatever */
> #include "PythonFunctionDoFuncs.h"
> #undef DOFUNC
> 
> That way there's just the one table for both purposes.
> 
> 
> Then, you have two choices.  1) Throughout your code, call the functions with 
> the function pointers.  This basically entails prepending a "p" to all the 
> function names.  2) Use macros to do this for you:
> 
> #define PyNumber_Float pPyNumber_Float
> #define PyString_AsString pPyString_AsString
> 
> I can't think of a technique to table-ize the above.  There may be one that 
> I'm forgetting, but I don't think so.  Still, that's just two places to touch 
> for each Python function you use.
> 
> If you want to get fancier, you could have a single file which just lists the 
> Python functions you use, one per line.  Then, a script would generate both 
> the PythonFunctionDoFuncs.h and a PythonFunctionRedefines.h (with the above 
> macro definitions) from that list.


#!/usr/bin/env lua

funcs = ""
loaders = "BOOL\tPython_LoadFunctions()\n{\n"
defs = ""
for line in io.lines("PythonFunctions.def") do
        funcs = funcs .. string.format("typeof(%s) *p%s\n", line, line)
        loaders = loaders .. string.format("if (!(p%s = dlsym(handle, 
\"%s\")))\n{\n" ..
                "fprintf(stderr, "Failed to load %s\n");\ngoto bail;\n}\n", 
line, line, line)
        defs = defs .. string.format("#define %s p%s\n", line, line)
end
loaders = loaders .. "return YES;\nbail:\nreturn NO;\n}\n"

io.open("PythonFunctions.h", "w"):write(funcs .. "\n" .. loaders .. "\n" .. 
defs)
-- EOF

Disclaimer: Written entirely in Mail and untested. Lua is not installed by 
default on Mac OS! Do it in Python instead, which I don't know enough to give 
the example in.

Set up an Xcode build rule in your target for files matching the pattern 
"PythonFunctions.def" and containing this script, with 
$(DERIVED_FILES_DIR)/PythonFunctions.h as the output file. Then #include the 
file in your source; Xcode should do the right thing from there.

-- Gwynne

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to