Renaming C struct properties using SWIG %apply - swig

I have the below structure in my SWIG interface file and thusly my sample.h header file. I'm assuming the sockaddr, ios_boolean and unsigned char definitions from this structure are the reason why I get the below generated classes. If I know the type on that ios_boolean and unsigned char map to on the Java side is there a way to use an %apply to get rid of the generated pointer classes? I tried %apply int {ios_boolean}; but then I get a SWIGTYPE_p_boolean.java. Any ideas?
%rename (Sample) sample_details_t_;
typedef struct sample_details_t_ {
ios_boolean is_allowed;
unsigned char mac[11];
} sample_t;
generates:
SWIGTYPE_p_unsigned_char.java
SWIGTYPE_p_ios_boolean.java
Exception:
[exec] ewapi_wrap.c:982: error: `true' undeclared (first use in this function)
[exec] ewapi_wrap.c:982: error: (Each undeclared identifier is reported only once
[exec] ewapi_wrap.c:982: error: for each function it appears in.)
[exec] ewapi_wrap.c:982: error: `false' undeclared (first use in this function

You probably want to do something like:
%include <arrays_java.i>
%rename (Sample) sample_details_t_;
%apply bool { ios_boolean };
typedef struct sample_details_t_ {
ios_boolean is_allowed;
unsigned char mac[11];
} sample_t;
This wraps mac as short[] (with constraints on the array size) and is_allowed as boolean on the Java side and results in these files:
Sample.java test.java testJNI.java
Make sure you delete any old SWIGTYPE_*.java files that are lying around from older versions of your SWIG interface, they won't get deleted automatically and might fail to compile if you do something like javac *.java.

Related

exposing nonstatic member function of class to chaiscript

I have a project that tries to implement keyboard macro scripting with chaiscript. I am writing a class based on xlib to wrap the xlib code.
I have a member function to add a modifier key to an ignored list, because of a xlib quirk.
how could i do something like the following minimal example.
#include <chaiscript/chaiscript.hpp>
#include <functional>
class MacroEngine{
public:
MacroEngine() = default;
//...
void addIgnoredMod(int modifier){
ignoredMods |= modifier;
}
//...
private:
int ignoredMods;
};
int main(int argc, char *argv[]){
MacroEngine me;
chaiscript::ChaiScript chai;
//...
chai.add(chaiscript::fun(std::bind(&MacroEngine::addIgnoredMod, me, std::placeholders::_1)), "setIgnoredMods");
//...
return 0;
}
I tried bind and failed with the following error message:
In file included from ../deps/ChaiScript/include/chaiscript/dispatchkit/proxy_functions_detail.hpp:24:0,
from ../deps/ChaiScript/include/chaiscript/dispatchkit/proxy_functions.hpp:27,
from ../deps/ChaiScript/include/chaiscript/dispatchkit/proxy_constructors.hpp:14,
from ../deps/ChaiScript/include/chaiscript/dispatchkit/dispatchkit.hpp:34,
from ../deps/ChaiScript/include/chaiscript/chaiscript_basic.hpp:12,
from ../deps/ChaiScript/include/chaiscript/chaiscript.hpp:823,
from ../src/main.cpp:2:
../deps/ChaiScript/include/chaiscript/dispatchkit/callable_traits.hpp: In instantiation of ‘struct chaiscript::dispatch::detail::Callable_Traits<std::_Bind<void (MacroEngine::*(MacroEngine, std::_Placeholder<1>))(unsigned int)> >’:
../deps/ChaiScript/include/chaiscript/language/../dispatchkit/register_function.hpp:45:72: required from ‘chaiscript::Proxy_Function chaiscript::fun(const T&) [with T = std::_Bind<void (MacroEngine::*(MacroEngine, std::_Placeholder<1>))(unsigned int)>; chaiscript::Proxy_Function = std::shared_ptr<chaiscript::dispatch::Proxy_Function_Base>]’
../src/main.cpp:21:95: required from here
../deps/ChaiScript/include/chaiscript/dispatchkit/callable_traits.hpp:99:84: error: decltype cannot resolve address of overloaded function
typedef typename Function_Signature<decltype(&T::operator())>::Signature Signature;
^~~~~~~~~
../deps/ChaiScript/include/chaiscript/dispatchkit/callable_traits.hpp:100:86: error: decltype cannot resolve address of overloaded function
typedef typename Function_Signature<decltype(&T::operator())>::Return_Type Return_Type;
^~~~~~~~~~~
I also tried to make the variable static which worked, but it wont work if I try to make it possible to ignore modifiers on a per hotkey basis.
what am i doing wrong? and how can I fix it?
You can do this instead:
chai.add(chaiscript::fun(&MacroEngine::addIgnoredMod, &me), "addIgnoredMod");
Or use a lambda:
chai.add(chaiscript::fun([&me](int modifier){ me.addIgnoredMod(modifier); }), "addIgnoredMod");
Jason Turner, the creator of Chaiscript, commented on it here: http://discourse.chaiscript.com/t/may-i-use-std-bind/244/4
"There’s really never any good reason to use std::bind. I much better solution is to use a lambda (and by much better, I mean much much better. std::bind adds to compile size, compile time and runtime)."

why the output of this program comes only by using extern ? Why not without it?

#include<stdio.h>
int main ()
{
printf("%d\n",z);
return 0;
}
int z=25;
why is output to this code is showing an error ?
The order in which you declare your functions/variables count in C. In your code, when the compiler parses your code, it encounters the symbol z, which has not yet been declared.
So, you need to put your int z = ... before the first time you use z, hence before main.
The extern keyword tells the compiler that the variable has been declared in another file, so it will be resolved during linking, i.e. when all the files are assembled into a program. So for the compilation of this file, the unresolved symbol z can be ignored => no compilation error.
Try this :
#include<stdio.h>
int z=25;
int main ()
{
printf("%d\n",z);
return 0;
}

how can the vim script(clang_complete ) complete function ,template?

In the clang_complete.txt(the help file), it shows these in clang_complete-compl_kinds:
2.Completion kinds *clang_complete-compl_kinds*
Because libclang provides a lot of information about completion, there are
some additional kinds of completion along with standard ones (see >
:help complete-items for details):
'+' - constructor
'~' - destructor
'e' - enumerator constant
'a' - parameter ('a' from "argument") of a function, method or template
'u' - unknown or buildin type (int, float, ...)
'n' - namespace or its alias
'p' - template ('p' from "pattern")
the question are:
1. i cannot access the complete-items(no this file)
2. can someone tell me how to use the parameter '+' 'a' and so on.
3. or can you tell me how to show function parameters when ( is typed.
thanks!
(forgive my poor english)
It's been a long time, but i'll answer to help future visitors.
I don't fully understand your questions, but I'll answer the 3rd one. Clang complete only launches automatic suggestion/completion when writing '.', '->' or '::', but you can launch it manually.
I use it this way. In this source:
#include <iostream>
using namespace std;
void ExampleFunc (float foo, int &bar)
{
cout << foo;
bar++;
}
int main (int argc, char **argv)
{
int a(0);
Exa[cursor here]
return 0;
}
Writing "Exa" you can press <C-X><C-U> and you will get a preview window with:
Example (float foo, int &bar)
and a completion window (the same that appears when you press <C-N> (CTRL-N) in insert mode) with:
Example f void Example(float foo, int &bar)
If there are several matches, you can move down or up with <C-N> or <C-P> and complete with <CR> (enter).
The completion is not perfect, but it should work for many other cases, for example (as you mentioned) templates:
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
struct MyType {int asdf; float qwer;};
vector<MyType> vec;
ve // suggestions after <C-X><C-U>:
// "vec v vector<MyType> vec" v is for variable
// "vector p vector<Typename _Tp>" p is for pattern (template)
// constructors with its parameters, etc.
vec. // auto-fired suggestions: all std::vector methods
vec[0]. // auto-fired suggestions: "asdf", "qwer" and MyType methods
return 0;
}
If those examples don't work for you, you haven't installed the plugin properly.
By the way, you can map <C-X><C-U> to other shortcut.

SWIG Convert unsigned char* to 20 byte buffer Java structure

I have a C function (composeKey) that has an input unsigned char* parameter ("key"). On the C side, "key" needs to be an empty 20 byte buffer structure. I'm assuming that a Java short array with a size of 20 would be the correct Java structure to pass composeKey's "key" parameter, but I'm unsure. Maybe a byte[20] is what i need. If that is correct, what SWIG Interface file modification is needed to generate the composeKey Java method with a short[] as input for the "key" parameter?
C Function:
int composeKey(const void* secret, int secret_len, unsigned char* key, int length);
Solution to your specific problem
Java doesn't really distinguish between short[20] and (e.g.) short[21] in its type system. You can do something that's pretty sensible quite simply though, by making the fact that the length of key is always 20 obvious to SWIG:
%module test
%include "arrays_java.i"
int func(unsigned char key[20]);
This can work even without changing the actual signature of your function directly - SWIG can wrap that, but have the wrapped code call a function that still takes unsigned char* quite sensibly:
%module test
%{
#include "header.h"
// fine even if it's func(unsigned char *key) in the header.
%}
%include "arrays_java.i"
int func(unsigned char key[20]);
If you call func from Java with an inappropriately sized array you'll get an IndexOutOfBoundsException exception thrown for you automatically by the code that SWIG generates.
General solution
In this specific case "arrays_java.i" provides a suitable typemap already. In the more general case this works by providing SWIG with a typemap for unsigned char [ANY] (literally write ANY in SWIG typemap syntax). This then gets instantiated for specific values in place of ANY (sort of like a template in C++), you can then access the specific value of ANY in your typemap using $1_size and supply code that the sizes gets filled in to look (some JNI details omitted for brevity) roughly like:
if (GetArrayLength(arg) != $1_size) {
// Code to throw a Java Exception ...
Which then in the generated wrapper becomes:
if (GetArrayLength(arg) != 20) {
// Code to throw a Java Exception ...

C++ Calling Static member function from external file

I have this class defined in Global.h
class Global
{
public:
static string InttoStr(int num);
};
In Global.cpp, i have
Global::InttoStr(int num)
{
//Code To convert integer into string.
}
Now, from SubMove.cpp, when i call Global::InttoStr(num) I get following error:
error LNK2019: unresolved external symbol Global::InttoStr(int) referenced in function SubMove::toString(void)
Then I made the function non-static and called it like so:
Global g;
g.InttoStr(num);
But the error still persists.
I thought it had something to do with extern and searched it but i could not make any connection. Please help.
First off, try this:
string Global::InttoStr(int num)
{
//Code To convert integer into string.
}
Also, are you calling InttoStr from another library ? If so, you'll need to export the class "Global".
Best practice is to use a lib header (in the example below replace LIB_ with the name of the library):
#ifndef SOME_LIB_HEADER
#define SOME_LIB_HEADER
#if defined (LIB_EXPORTS)
#define LIB_API __declspec(dllexport)
#else
#define LIB_API __declspec(dllimport)
#endif // SOME_LIB_HEADER
Define LIB_EXPORTS in your project contianing Global, include the lib header in Global.h, then define the class like this
class LIB_API Global
{
// some code for the class definition
};
Each project should have its own LIB_EXPORTS and LIB_API definition like DLL1_EXPORTS, DLL1_API, DLL2_EXPORTS, DLL2_API etc.
Basically this makes a separate lib treat the previous dll with __declspec(dllimport) and resolve all externs.