We use a third party Tcl parsing library to validation Tcl script for both syntax and semantic checking. The driver was written in C and defined a set of utility functions. Then it calls Tcl_CreateObjCommand so the script could call these C functions. Now we are in the process of porting the main program to go and I could not find a way to do this. Anyone know a way to call golang functions from Tcl script?
static int
create_utility_tcl_cmds(Tcl_Interp* interp)
{
if (Tcl_CreateObjCommand(interp, "ip_v4_address",
ip_address, (ClientData)AF_INET, NULL) == NULL) {
TCL_CHECKER_TCL_CMD_EVENT(0, "ip_v4_address");
return -1;
}
.....
return 0;
}
Assuming you've set the relevant functions as exported and built the Go parts of your project as in
Using Go code in an existing C project
[…]
The important things to note are:
The package needs to be called main
You need to have a main function, although it can be empty.
You need to import the package C
You need special //export comments to mark the functions you want callable from C.
I can compile it as a C callable static library with the following command:
go build -buildmode=c-archive foo.go
Then the core of what remains to be done is to write the C glue function from Tcl's API to your Go code. That will involve a function something like:
static int ip_address_glue(
ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) {
// Need an explicit cast; ClientData is really void*
GoInt address_family = (GoInt) clientData;
// Check for the right number of arguments
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "address");
return TCL_ERROR;
}
// Convert the argument to a Go string
GoString address;
int len;
address.p = Tcl_GetStringFromObj(objv[1], &len);
address.n = len; // This bit is hiding a type mismatch
// Do the call; I assume your Go function is called ip_address
ip_address(address_family, address);
// Assume the Go code doesn't fail, so no need to map the failure back to Tcl
return TCL_OK;
}
(Credit to https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf for providing enough information for me to work out some of the type bindings.)
That's then the function that you register with Tcl as the callback.
Tcl_CreateObjCommand(interp, "ip_v4_address", ip_address_glue, (ClientData)AF_INET, NULL);
Theoretically, a command registration can fail. Practically, that only happens when the Tcl interpreter (or a few critical namespaces within it) is being deleted.
Mapping a failure into Tcl is going to be easiest if it is encoded at the Go level as an enumeration. Probably easiest to represent success as zero. With that, you'd then do:
GoInt failure_code = ip_address(address_family, address);
switch (failure_code) {
case 0: // Success
return TCL_OK;
case 1: // First type of failure
Tcl_SetResult(interp, "failure of type #1", TCL_STATIC);
return TCL_ERROR;
// ... etc for each expected case ...
default: // Should be unreachable, yes?
Tcl_SetObjResult(interp, Tcl_ObjPrintf("unexpected failure: %d", failure_code));
return TCL_ERROR;
}
Passing back more complex return types with tuples of values (especially a combination of a success indicator and a “real” result value) should also be possible, but I've not got a Go development environment in order to probe how they're mapped at the C level.
Related
I have a structure in C and I called that structure in my go program. If that structure throws any error it terminates my go program like below
orderbook.h
-------------
#ifndef _ORDERBOOK_H
#define _ORDERBOOK_H
typedef struct order order;
struct order {
int tradeid;
int side;
int symbol;
double amount;
double price;
};
orderbook.c
--------------
include "orderbook.h"
order* order_place(char *side,double amount,double price,char symbol[19])
{
struct order *tradeorder= calloc(1000000,sizeof(struct order));//Initlize the structure
//My internal code which place an order
clob_ord_t o=unxs_order(c, (clob_ord_t){CLOB_TYPE_LMT,parsed_side, amount, .lmt =price, .usr = (uintptr_t)out},NANPX);
if (o.qty.dis + o.qty.hid > 0.dd) {
/* put remainder of order into book */
i = clob_add(c, o);
//printf("orderid..%lu\n", i.usr);
printf("orderid..%s\n", i.usr);
insertMap(hashTable, i.usr, i);
// printMap(hashTable);
flag=true;
tradeorder[0].orderstatus=1;
tradeorder[0].orderid=offerid;
tradeorder[0].side=sid;
tradeorder[0].symbol=atoi(symbol);
tradeorder[0].amount=(double)o.qty.dis;
tradeorder[0].price=price;
}
return tradeorder; //return the structure
}
main.go
---------
o:=C.order_place(C.CString("ASK"),C.double(12.0),C.double(1.0),C.CString("1")) //this line may get an exception If some wrong parameter to pass otherwise returns correct value
If I put correct parameter to order_pace function from go there is no issue, If I pass some incorrect parameter then In get an exception an it terminates the go server. Now I need to handle that exception so that my server remain running irrespective of an exception.
You can't catch the fatal fault, and it isn't safe to continue after your C code throws a fault (unlike Go). The running program is in an undefined potentially dangerous state. The safest thing to do is shutdown the program and/or let it crash.
You must check for errors within C.order_place and return an error on failure. Eg, return NULL.
A few other recommendations:
Allocate struct order via Go to rely on the garbage collector to simplify memory management.
var order C.struct_order
C.order_place(&order, side, ...)
Always free strings allocated via C.CString once they are no longer needed.
cstr := C.CString("test")
C.free(unsafe.Pointer(cstr))
Depending on your platform, you can simplify debugging with improved stack traces by importing cgosymbolizer. This adds support for C stack traces.
import _ "github.com/ianlancetaylor/cgosymbolizer"
You probably should use char *symbol instead of char symbol[19] in your example since C.CString returns a pointer to an arbitrarily long C string, not a pointer to an array of 19 chars.
I'm trying to write a really small C extension. So I don't want to make a whole ruby class, with initializer, allocator, and so forth. All I want to do is add a static method to an existing class, method which will run an algorithm and return a result. Unfortunately, all documentation I find only speak about wrapping a C struct into a VALUE, but that's not my use case.
What I want to know : if I create a ruby object (which will allocate memory) inside my C code, and that I return it as the result of my function, will it be taken care of properly by the garbage collector, or is it going to leak ?
Example :
void Init_my_extension()
{
VALUE cFooModule;
cFooModule = rb_const_get(rb_cObject, rb_intern("Foo"));
rb_define_singleton_method(cFooModule, "big_calc", method_big_calc, 1);
}
VALUE method_big_calc(VALUE self, VALUE input)
{
VALUE result;
result = rb_ary_new();
return result;
}
Will the array that was allocated by rb_ary_new() be properly cleaned when it's not used anymore ? How is the garbage collector aware of references to this value ?
Yes, You code properly clean memory if You using rb_ary_new().
In my opinion You need answer on other question. How create you own object.
http://www.onlamp.com/pub/a/onlamp/2004/11/18/extending_ruby.html
first You must create rb_define_alloc_func(cYouObject,t_allocate);
similar this
struct stru { char a; };
void t_free(struct stru *a) { }
static VALUE t_allocate(VALUE obj) { return
Data_Wrap_Struct(obj,NULL,t_free,m); }
I was trying to understand how Linux system calls return error codes. I bumped into times() system call. This simple system call copies some data to user space and if that operation was not successful returns -EFAULT:
SYSCALL_DEFINE1(times, struct tms __user *, tbuf)
{
if (tbuf) {
struct tms tmp;
do_sys_times(&tmp);
if (copy_to_user(tbuf, &tmp, sizeof(struct tms)))
return -EFAULT;
}
force_successful_syscall_return();
return (long) jiffies_64_to_clock_t(get_jiffies_64());
}
My questions are:
Why -EFAULT? Shouldn't it be EFAULT without minus?
Is it a common to return negative error codes?
From man 2 syscalls:
Note: system calls indicate a failure by returning a negative error number to the caller; when this happens, the wrapper function negates the returned error number (to make it positive), copies it to errno, and returns -1 to the caller of the wrapper.
See also next answers:
What are the return values of system calls in Assembly?
Why doesn't a custom system call work properly with negative numbers?
I'm writing an Windows phone application with C++/CX. The function tries to copy input array to output array asynchronously:
IAsyncAction CopyAsync(const Platform::Array<byte, 1>^ input, Platform::WriteOnlyArray<byte, 1>^ output)
{
byte *inputData = input->Data;
byte *outputData = output->Data;
int byteCount = input->Length;
// if I put it here, there is no error
//memcpy_s(outputData, byteCount, inputData, byteCount);
return concurrency::create_async([&]() -> void {
memcpy_s(outputData, byteCount, inputData, byteCount); // access violation exception
return;
});
}
This function compiles but cannot run correctly and produces an "Access violation exception". How can I modify values in the output array?
This is Undefined Behaviour: by the time you use your 3 captured (by reference) variables inputData/outputData/byteCount in the lambda, you already returned from CopyAsync and the stack has been trashed.
It's really the same issue as if you returned a reference to a local variable from a function (which we know is evil), except that here the references are hidden inside the lambda so it's a bit harder to see at first glance.
If you are sure that input and output won't change and will still be reachable between the moment you call CopyAsync and the moment you run the asynchronous action, you can capture your variables by value instead of by reference:
return concurrency::create_async([=]() -> void {
// ^ here
memcpy_s(outputData, byteCount, inputData, byteCount);
return;
});
Since they're only pointers (and an int), you won't be copying the pointed-to data, only the pointers themselves.
Or you could just capture input and output by value: since they're garbage-collected pointers this will at least make sure the objects are still reachable by the time you run the lambda:
return concurrency::create_async([=]() -> void {
memcpy_s(output->Data, input->Length, input->Data, input->Length);
return;
});
I for one prefer this second solution, it provides more guarantees (namely, object reachability) than the first one.
Google's v8 documentation describes how to add a global function to a JavaScript context. We can implement a printf-like function quite easily using the new lambda feature from C++11:
Handle<ObjectTemplate> global = ObjectTemplate::New();
global->Set(String::New("print"), FunctionTemplate::New(
[](const v8::Arguments &args) -> v8::Handle<v8::Value>
{
v8::String::AsciiValue ascii(args[0]);
std::cout << *ascii << "\n";
} ));
Persistent<Context> context = Context::New(NULL, global);
This works well for any global JavaScript function that is either stateless or references a global C++ variable (i.e. std::cout). But what if we want our global JavaScript function to reference a non-global C++ variable? For example, suppose we are creating several different JavaScript contexts each with its own global print function that uses a different C++ std::ostream? If v8 function templates used std::function objects instead of function pointers, the we would do something like this:
Persistent<Context> create_context(std::ostream &out)
{
Handle<ObjectTemplate> global = ObjectTemplate::New();
global->Set(String::New("print"), FunctionTemplate::New(
[&out](const v8::Arguments &args) -> v8::Handle<v8::Value>
{
v8::String::AsciiValue ascii(args[0]);
out << *ascii << "\n";
} ));
return Context::New(NULL, global);
}
Unfortunately, v8 does not seem to support this. I assume (hope?) that v8 has a way of doing something functionally equivalent, but I find myself mystified by the Doxygen for v8::FunctionTemplate. Would anyone who has attempted something similar be willing to distill the process down into something more understandable? I would also like to learn how to create a global instance of a JavaScript object that is bound to an existing, non-global instance of a C++ object.
In answer to my own question... the key is to realize that v8::Arguments is not simply an array of arguments. It also contains the exceedingly useful Callee() and Data() methods. If the function is a method of a JavaScript object then Callee() can, I think, be used to get ahold of whatever instance of that object the method was called on. Useful state information could then be stored in the object instance. You can also supply a data handle, which may point to any C++ object through void*, when adding a function template to an object. This function-specific data handle may then be accessed through the Data() method.
Below is a reasonably complete example of what I was trying to do in the question using v8::Arguments::Data(). Hopefully this will be useful to anyone who wants to do something similar. If you have an alternative strategy you like (and I am certain there is more than one way of doing this), please feel free to add it in another answer!
#include <iostream>
#include <ostream>
#include <v8.h>
// add print() function to an object template
void add_print(v8::Handle<v8::ObjectTemplate>& ot, std::ostream* out)
{
// add function template to ot
ot->Set(v8::String::New("print"), v8::FunctionTemplate::New(
// parameter 1 is the function callback (implemented here as a lambda)
[](const v8::Arguments& args)->v8::Handle<v8::Value>
{
// recover our pointer to an std::ostream from the
// function template's data handle
v8::Handle<v8::External> data = v8::Handle<v8::External>::Cast(args.Data());
std::ostream* out = static_cast<std::ostream*>(data->Value());
// verify that we have the correct number of function arguments
if ( args.Length() != 1 )
return v8::ThrowException(v8::String::New("Too many arguments to print()."));
// print the ascii representation of the argument to the output stream
v8::String::AsciiValue ascii(args[0]);
*out << *ascii << "\n";
// like 'return void;' only in JavaScript
return v8::Undefined();
},
// parameter 2 is the data handle with the pointer to an std::ostream
v8::External::New(out)
));
}
int main()
{
// create a stack-allocated handle scope
v8::HandleScope handle_scope;
// create a global template
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
// add a print() function using std::cout to the global template
add_print(global, &std::cout);
// create a context
v8::Persistent<v8::Context> context = v8::Context::New(nullptr, global);
// enter the created context
v8::Context::Scope context_scope(context);
// create a string containing the JavaScript source code
v8::Local<v8::String> source = v8::String::New("print('1 + 1 = ' + (1 + 1));");
// compile the source code
v8::Local<v8::Script> script = v8::Script::Compile(source);
// run the script
script->Run();
// dispose of the persistent context
context.Dispose();
return 0;
}