Push lua function as table member from C API - c

Well there are no problems to push C function as function member or register C function as lua function with lua_register(L, lua_func_name, c_func);
But how tell lua what i want to pass luaFoo() as function callback param for "foober" from C?
lua_pushcfunction - pushes C function, lua_pushstring pushes just a plain string, so callback field became a string, not a function.
Lua Code:
CALLBACKS = {};
FOO = 0;
function luaFoo()
FOO = FOO + 1;
end;
function addCallback(_name, _callback)
CALLBACKS[_name] = _callback;
end;
function doCallback(_name)
CALLBACKS[_name]();
end;
C code:
static int c_foo(lua_State* l)
{
printf("FOO\n");
return 0;
}
/*load lua script*/;
lua_State* l = /*get lua state*/;
lua_getglobal(l, "addCallback");
lua_pushstring(l, "foober");
//What push for luaFoo()
lua_pushcfunction(l, c_foo);
lua_call(l, 2, 0);
lua_getglobal(l, "doCallback");
lua_pushstring(l, "foober");
lua_call(l, 1, 0);
Similiar - if i get C functions which already registered with lua_register, how pass them as callback param from C. So we register c_foo => c_foo exist as lua function, how to tell what we want to pass "c_foo" as callback func param.

Remember that:
function luaFoo()
...
end
is equivalent to this, in Lua:
luaFoo = function()
...
end
Therefore, your question ultimately boils down to, "I have a value in the global table. How do I push it onto the stack?" The fact that this value is a function is irrelevant; a function value in Lua is no different from an integer value, which is no different than a string value. Obviously you can do different things with them, but you just want to copy them around. That works the same regardless of what the value is.
The function you're looking for is lua_getglobal.
As for your second question, you can do it in one of two ways. You can either get the function value you registered from the global table, or you can simply re-register it with lua_pushcfunction. Since you're not using upvalues, re-registering it doesn't really have any downsides.
Oh, and one more thing, on code style. Lua doesn't require ; at the end of statements. You can do it (to make C-native programmers feel more comfortable), but it's not necessary.

Related

Lifetime of Lua object "globally returned" to C

So I have a very simple Lua script like this:
return coroutine.create(function () coroutine.yield(1) end)
And then in C I run it and gets the returned value
lua_State* l = luaL_newstate();
if(luaL_dostring(l, script) == LUA_OK) {
lua_State* co = lua_tothread(l, lua_gettop(l));
lua_pop(l, 1);
}
Later, the C code will pass the co pointer back into Lua (with lua_pushthread) and run coroutine.resume(co).
I would like to know if Lua will GC the coroutine object in the meantime, rendering the co pointer in C invalid? If yes, what can I do to prevent that?
With a little care, you can just leave the coroutine in the stack. Just remove the call to lua_pop.

How can I use global variables used between two C function which are called in Modelica?

I have two function definitions in C which share some global variables. I want to call these functions in Modelica but I do not know how can I correctly keep the value of the global variable between two function calls.
file.c
/*Global variable definition*/
int* global_test1;
void FirstFunc (const int* init_value){
memcpy(global_test1, init_value, 2*sizeof(int));
}
void SecondFunc(int* some_output_variable){
memcpy(some_output_variable, global_test1, 2*sizeof(int));
}
calling_FirstFunc.mo
function calling_FirstFunc
input Integer[2,1] init_value = [3;3];
external "C" FirstFunc(init_value);
end;
calling_SecondFunc.mo
function calling_SecondFunc
output Integer[2,1] output_var;
external "C" SecondFunc(output_var);
end;
model.mo
model Calling_TwoFuncs
Integer[2,1] input_var = [3;5];
Integer[2,1] output_var;
equation
calling_FirstFunc(input_var);
when time>5.0 then
output_var = calling_SecondFunc();
end when;
end Calling_TwoFuncs;
Your sample code should almost work correctly. The C-functions will keep their state and work fine if (and only if) they are called in the order First, Second. You also need to allocate memory for global_test1... But this order is not guaranteed in the code. I suggest using external objects instead; then you can create multiple instances of the same model and not have a global state in the C-code (because you can malloc memory and return this for the constructor call; the First call). Note that you should probably pass the size of the vector to the constructor in order to be more general.

How to set a "require" to return a table/module from Lua C API?

I want to add a requireable module solely from the C API.
--lua.lua
local c_module = require("c_module")
c_module.doWork()
What API functions do I have to use to make this possible?
When loading a shared library with require, Lua looks for a a function named luaopen_<name> where <name> is the module name with the dots replaced with underscores (so require "foo.bar" will look for luaopen_foo_bar, but hyphens get special treatment; see the Lua manual).
This function should be a regular lua_CFunction; that is, it takes a lua_State* as an argument and returns an int. require calls this function with the package name as an argument, and the value you return from the function is what require stores and returns.
Here's an example for a module named foo:
static int bar(lua_State* L) {
// ...
}
int luaopen_foo(lua_State* L) {
lua_newtable(L); // Create package table
// Push and assign each function
lua_pushcfunction(L, &bar);
lua_setfield(L, -2, "bar");
// ...
// Return package table
return 1;
}
(This is for Lua 5.1, though the equivalent code for 5.2 should be very similar, if not the same. Also be sure that the luaopen_ function is exported from the shared library.)
The full behavior of the C loader can be found here: http://www.lua.org/manual/5.1/manual.html#pdf-package.loaders

return several parameter from lua C function

I want to get several parameters in Lua from a C function.
I tried to push several arguments on the lua stack:
static int myFunc(lua_State *state)
{
lua_pushnumber(state, 1);
lua_pushnumber(state, 2);
lua_pushnumber(state, 3);
return 1;
}
and call it in Lua like this:
local a,b,c = myFunc()
Unfortunately b and c values are nil. I dont want to write a function for every value I need but to take advantage of Luas capabilities to retrieve several arguments from a function.
The return value of the C function is the number of values returned.
Change it to return 3; and you're good to go.
Here, have a reference from Programming in Lua:
static int l_sin (lua_State *L) {
double d = lua_tonumber(L, 1); /* get argument */
lua_pushnumber(L, sin(d)); /* push result */
return 1; /* number of results */
}

Call Go functions from C

I am trying to create a static object written in Go to interface with a C program (say, a kernel module or something).
I have found documentation on calling C functions from Go, but I haven't found much on how to go the other way. What I've found is that it's possible, but complicated.
Here is what I found:
Blog post about callbacks between C and Go
Cgo documentation
Golang mailing list post
Does anyone have experience with this? In short, I'm trying to create a PAM module written entirely in Go.
You can call the Go code from C. It is a confusing proposition, though.
The process is outlined in the blog post you linked to. But I can see how that isn't very helpful. Here is a short snippet without any unnecessary bits. It should make things a little clearer.
package foo
// extern int goCallbackHandler(int, int);
//
// static int doAdd(int a, int b) {
// return goCallbackHandler(a, b);
// }
import "C"
//export goCallbackHandler
func goCallbackHandler(a, b C.int) C.int {
return a + b
}
// This is the public function, callable from outside this package.
// It forwards the parameters to C.doAdd(), which in turn forwards
// them back to goCallbackHandler(). This one performs the addition
// and yields the result.
func MyAdd(a, b int) int {
return int( C.doAdd( C.int(a), C.int(b)) )
}
The order in which everything is called is as follows:
foo.MyAdd(a, b) ->
C.doAdd(a, b) ->
C.goCallbackHandler(a, b) ->
foo.goCallbackHandler(a, b)
The key to remember here is that a callback function must be marked with the //export comment on the Go side and as extern on the C side. This means that any callback you wish to use, must be defined inside your package.
In order to allow a user of your package to supply a custom callback function, we use the exact same approach as above, but we supply the user's custom handler (which is just a regular Go function) as a parameter that is passed onto the C side as void*. It is then received by the callbackhandler in our package and called.
Let's use a more advanced example I am currently working with. In this case, we have a C function that performs a pretty heavy task: It reads a list of files from a USB device. This can take a while, so we want our app to be notified of its progress. We can do this by passing in a function pointer that we defined in our program. It simply displays some progress info to the user whenever it gets called. Since it has a well known signature, we can assign it its own type:
type ProgressHandler func(current, total uint64, userdata interface{}) int
This handler takes some progress info (current number of files received and total number of files) along with an interface{} value which can hold anything the user needs it to hold.
Now we need to write the C and Go plumbing to allow us to use this handler. Luckily the C function I wish to call from the library allows us to pass in a userdata struct of type void*. This means it can hold whatever we want it to hold, no questions asked and we will get it back into the Go world as-is. To make all this work, we do not call the library function from Go directly, but we create a C wrapper for it which we will name goGetFiles(). It is this wrapper that actually supplies our Go callback to the C library, along with a userdata object.
package foo
// #include <somelib.h>
// extern int goProgressCB(uint64_t current, uint64_t total, void* userdata);
//
// static int goGetFiles(some_t* handle, void* userdata) {
// return somelib_get_files(handle, goProgressCB, userdata);
// }
import "C"
import "unsafe"
Note that the goGetFiles() function does not take any function pointers for callbacks as parameters. Instead, the callback that our user has supplied is packed in a custom struct that holds both that handler and the user's own userdata value. We pass this into goGetFiles() as the userdata parameter.
// This defines the signature of our user's progress handler,
type ProgressHandler func(current, total uint64, userdata interface{}) int
// This is an internal type which will pack the users callback function and userdata.
// It is an instance of this type that we will actually be sending to the C code.
type progressRequest struct {
f ProgressHandler // The user's function pointer
d interface{} // The user's userdata.
}
//export goProgressCB
func goProgressCB(current, total C.uint64_t, userdata unsafe.Pointer) C.int {
// This is the function called from the C world by our expensive
// C.somelib_get_files() function. The userdata value contains an instance
// of *progressRequest, We unpack it and use it's values to call the
// actual function that our user supplied.
req := (*progressRequest)(userdata)
// Call req.f with our parameters and the user's own userdata value.
return C.int( req.f( uint64(current), uint64(total), req.d ) )
}
// This is our public function, which is called by the user and
// takes a handle to something our C lib needs, a function pointer
// and optionally some user defined data structure. Whatever it may be.
func GetFiles(h *Handle, pf ProgressFunc, userdata interface{}) int {
// Instead of calling the external C library directly, we call our C wrapper.
// We pass it the handle and an instance of progressRequest.
req := unsafe.Pointer(&progressequest{ pf, userdata })
return int(C.goGetFiles( (*C.some_t)(h), req ))
}
That's it for our C bindings. The user's code is now very straight forward:
package main
import (
"foo"
"fmt"
)
func main() {
handle := SomeInitStuff()
// We call GetFiles. Pass it our progress handler and some
// arbitrary userdata (could just as well be nil).
ret := foo.GetFiles( handle, myProgress, "Callbacks rock!" )
....
}
// This is our progress handler. Do something useful like display.
// progress percentage.
func myProgress(current, total uint64, userdata interface{}) int {
fc := float64(current)
ft := float64(total) * 0.01
// print how far along we are.
// eg: 500 / 1000 (50.00%)
// For good measure, prefix it with our userdata value, which
// we supplied as "Callbacks rock!".
fmt.Printf("%s: %d / %d (%3.2f%%)\n", userdata.(string), current, total, fc / ft)
return 0
}
This all looks a lot more complicated than it is. The call order has not changed as opposed to our previous example, but we get two extra calls at the end of the chain:
The order is as follows:
foo.GetFiles(....) ->
C.goGetFiles(...) ->
C.somelib_get_files(..) ->
C.goProgressCB(...) ->
foo.goProgressCB(...) ->
main.myProgress(...)
It is not a confusing proposition if you use gccgo. This works here:
foo.go
package main
func Add(a, b int) int {
return a + b
}
bar.c
#include <stdio.h>
extern int go_add(int, int) __asm__ ("example.main.Add");
int main() {
int x = go_add(2, 3);
printf("Result: %d\n", x);
}
Makefile
all: main
main: foo.o bar.c
gcc foo.o bar.c -o main
foo.o: foo.go
gccgo -c foo.go -o foo.o -fgo-prefix=example
clean:
rm -f main *.o
The answer has changed with the release of Go 1.5
This SO question that I asked some time ago addresses the issue again in light of the 1.5 added capabilities
Using Go code in an existing C project
As far as I am concerned it isn't possible:
Note: you can't define any C functions in preamble if you're using
exports.
source: https://github.com/golang/go/wiki/cgo

Resources