[CM] s7 - howto use s7_define_function_star in a C++ project.

Jason Ripley ripley.jason at gmail.com
Thu Feb 12 13:46:12 PST 2015


Thanks for your input everyone.  I got it working in a bare bones project.
I am still having the original problem in my actual program which is using
s7 as an extension language in the Cocos2d-x game engine, but now I am sure
the problem lies with Cocos2d-x.  It was ported from objective C to C++, so
a lot of the pointer stuff is odd.

Here is the working sample C++ project in case it is of use to anyone:

//Scheme.h
#ifndef __SCHEME_H__
#define __SCHEME_H__

#include "s7.h"
#include "stdlib.h"

extern "C" {

class Scheme
{
public:
        static s7_pointer plus(s7_scheme *sc, s7_pointer args);
        Scheme();
        ~Scheme();
        int addFFItoScheme();
        int testFFI();
private:
        static s7_scheme* s7;
};
}
#endif

//Scheme.cpp
#include "s7.h"
#include "Scheme.h"
#include <stdlib.h>
#include <iostream>

s7_scheme*  Scheme::s7;
s7_pointer Scheme::plus(s7_scheme *sc, s7_pointer args)
{
        /* (define* (plus (red 32) blue) (+ (* 2 red) blue)) */
        return(s7_make_integer(sc, 2 * s7_integer(s7_car(args)) +
s7_integer(s7_car(s7_cdr(args)))));
}

Scheme::Scheme() {
        s7 = s7_init();
        std::cout << "Scheme init\n";
}

Scheme::~Scheme() {
        free(s7);
        std::cout << "Bye!\n";
}

int Scheme::addFFItoScheme()
{
        std::cout << "addFFItoScheme\n";
        s7_define_function_star(s7, "plus", Scheme::plus, "(red 32) blue",
"an example of define* from C");
        return 0;
}

int Scheme::testFFI()
{
        std::cout << "testFFI\n";
        auto val = s7_eval_c_string(s7, "(+ 2 3)"); // should be 5
        std::cout << "5 = " << s7_object_to_c_string(s7, val) << std::endl;
        val = s7_eval_c_string(s7, "(plus 2 3)"); // should be 7
        std::cout << "7 = " << s7_object_to_c_string(s7, val) << std::endl;
        return 0;
}

//main.cpp
#include "s7.h"
#include "Scheme.h"
#include "Scheme.cpp"

int main(int argc, char **argv)
{
        std::cout << "Main" << std::endl;
        Scheme* scheme = new Scheme();
        scheme->addFFItoScheme();
        scheme->testFFI();

}

//to build:
//g++ -c s7.c -I. -g
//g++ -c Scheme.cpp -I. -g -std=c++0x && g++ main.cpp -o ffi s7.o -I. -lm
-ldl -std=c++0x && ./ffi

and output is as expected:
Main
Scheme init
addFFItoScheme
testFFI
5 = 5
7 = 7

Thanks again for your help,
Jason

On Thu, Feb 12, 2015 at 10:39 AM, Ralf Mattes <rm at seid-online.de> wrote:

> On Thu, Feb 12, 2015 at 10:42:31AM -0500, Jason Ripley wrote:
>
> > should.  However, I cannot seem to find the correct invocation in C++ to
> > make it work.  I was wondering if it needs something like extern "C",
> which
> > I tried to no avail.
>
> Yes, when compiling with a C++ compiler you need to declare your calls into
> C as "extern C" otherwise you'll be the victim of name mangling.
>
>  Cheers, RalfD
>
>
> Yes, when compiling with a C++ compiler you need to declare your calls into
> C as "extern C" otherwise you'll be the victim of name mangling.
>
>  Cheers, RalfD
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://ccrma-mail.stanford.edu/mailman/private/cmdist/attachments/20150212/548f6aba/attachment.html 


More information about the Cmdist mailing list