Hi,
> I'm running into some problems with FFI. This is the method
> I am using:
>
> cgCreateProgram: ctx with: programtype with: program with:
> profile with: entry with: args
> "This method was automatically generated."
> "CGprogram cgCreateProgram(CGcontext ctx, CGenum
> program type, const char *program, CGprofile profile, const
> char *entry, const char **args);"
> <cdecl: ulong 'cgCreateProgram' (ulong ulong byte*
> ulong byte* byte** ) module: 'Cg'>
^^
And this is the problem. The FFI can't coerce arrays of pointers
automatically, so using "foo **" in any way is simply invalid.
> If I get ahold of the resulting CompiledMethod and look at the first
> literal, it is an ExternalLibraryFunction corresponding to the FFI
> spec. One thing that is odd is the contents of the
> 'argTypes' variable
> of the ELFunc: #(ulong ulong ulong byte* ulong byte* byte void).
> Why might the 'void' be there?
Looks like a parser error which should be fixed. "**" needs to raise an
error unless we fix the ffi plugin to do the right coercion, which ...
err .... seems hard.
> This brings me to my next question(s):
> - Will FFI know how to coerce a String to a 'byte*'?
Yes. The difference between "byte*" and "char*" is that "char*" will
force the argument (a String) to be converted into a zero-terminated C
string. For example
Stdio>>puts: aString
<cdecl: void 'puts' (char*)>
will allow you to use
Stdio new puts: 'Hello World'.
whereas using 'byte*' in the above will print out half of Squeak's
object memory.
> - What the heck do I do for 'byte**'?
> (The C function expects an array of null-terminated strings)
You need to assemble the arguments manually. Bert had a nice example
for this some time back (it was some socket related stuff) you may
want to google for it.
Cheers,
- Andreas