string arguments are not recognized by SWIG - c++

I have a frustrating problem which got me spend a lot of time dealing with it but I did not find any solution.
I want to use C++ class in PHP with SWIG. I generated my shared object and it works fine for some methods but I've got this error whenever I call the methods with string arguments as their input:
Fatal error: Type error in argument 2 of PKI_Buf_initHex. Expected SWIGTYPE_p_std__string
PKI_Buf_initHex is the name of the wrapper class which SWIG made automatically. In my C++ code I declare initHex method as:
int initHex(const string x)
{..}
I included typemaps.i and std_string.i in my interface file but I got the same error message.
I truly would appreciate if anyone can help me with this issue.

You need to have:
%include <std_string.i>
Early enough in the SWIG interface (i.e. before std::string is first seen).

Related

Why is my swig generated tcl code missing methods at runtime?

I am using swig 4.0.2 to generate a package for tcl use.
The source .i file contains lots of classes and the generated _wrap.cpp file contains the all the classes with their methods as I would expect and everything compiles ok with no warnings.
However, for at least 1 class, when I come to call a method on a instance from a tcl script I get a runtime error saying the method does not exist. The error also dumps out all the available methods of the class. The method I am trying to call, along with a few others, does not exist in that list.
Invalid method. Must be one of: configure cget -acquire -disown -delete ...
There doesn't appear to be any pattern to which methods are not in the list though it is consistent which methods are missing.
The missing methods are scattered through the declared swig interface. ie they aren't at the beginning or end, nor all in one block. There is no pattern to their names nor function signature that I can see.
The function being run when the error occurs is SWIG_Tcl_MethodCommand: a function generated by swig. It is responsible for looking up the method by name and printing out the error code.
The function wrappers all exist and are referenced in the class's swig_method array.
I would have imagined that if a method was not going to be found by the look up it would be all or nothing.
Does anyone have ideas where I could look for errors?
I'm afraid I haven't been able to isolate into a small testcase that I can share.
I'm using swig 4.02, generating code for tcl8 and compiling under c++ 14.
The problem is caused by copy and paste code.
A second swig package exists in the Project I'm working on. It redeclares the same class interface but with some methods missing!
If I sync up the declarations then everything works.
This leaves the question of how the original code with unsynced swig interfaces (that was generated with swig1.0) ever worked.

C++ missing information in compiler error

I'm trying to compile a Visual C++ 2013 project but the compiler is throwing this mysterious error:
Error 1 error C2338: The C++ Standard doesn't provide a hash for this type.
It does not tell me which class that is missing a hash, nor does it tell me in which file the error occurs. Rather, it links me to a line in the file xstdef which seem to be one of the compiler's libraries.
How can such critical information have been left out of the error message and how do I go about figuring out which class that is the perpetrator?
If you look at the Output tab, it will sometimes list more lines of code (e.g. template instance generated from file/line.) This can help you find the real problem - it will usually be from somewhere trying to USE the class, and not point directly to the class definition.
If you've made recent changes, you can try bisecting or stashing to find the change that introduced the error.

Template export troubles

I can't understand the right way for exporting some function into python with boost.python.
I have exported this class CL_Rectf. It inherits CL_Rectx<float>.
Now I want to export function bounding_rect:
# In CL_Rectf class exporting
.def("BoundingRect", &CL_Rectf::bounding_rect, PYPOLICY_REFERENCE_EXISTING)
It compiles, but when I use this code in python:
mBox = CL_Rectf()
mBox.BoundingRect(CL_Rectf(x, y, x2, y2))
I have such error:
Boost.Python.ArgumentError: Python argument types in
CL_Rectf.BoundingRect(CL_Rectf, CL_Rectf)
did not match C++ signature:
BoundingRect(CL_Rectf {lvalue}, CL_Rectx<float>)
Something wrong with exporting due to CL_Rectx in c++ signature. What's wrong?
Without knowing Boost.Python in particular, it seems to me that you exported CL_Rectf, but not CL_Rectx<float>. So when asked to convert a python object into a CL_Rectx<float>, Boost.Python doesn't know how, and raises the exception you see.
My advice would be be to forget about CL_Floatf and export the CL_Rectx<float> class instead. CL_Rectf as a C++ class is a bad idea on so many levels; you should try to avoid its use even in C++.

How to call a JNI DLL from C++

I have a task to interface with a dll from a third party company using C++.
The dll package comes with:
the dll itself
a sample Java implementation - consists of a java wrapper(library) generated using the SWIG tool and the the java source file
documentation that states all the public datatypes, enumeration and member functions.
My other colleague is using Java(based on the example in package) to interface with the dll while I'm asked to use C++. The Java example looks straight forward... just import the wrapper and instantiate any class described in the docs..
More info on the dll:
From the docs, it says the dll was programmed using C++
From a hexdump, it shows that it was compiled using VC90 (VS C++ 2008 right?) and something from Dinkumware.
From a depends.exe output, the functions seems to be wrapped under JNI. For example: _Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect#20
My dilemma:
The dll company is not changing anything in the dll and not providing any other info.
How do i use the member functions in the class from the dll?
I did some simple LoadLibrary() and GetProcAddress and manage to get the address of the public member functions.
But i dunno how to use the functions that has the datatype parameters defined in the dll. For example:
From the docs, the member function is defined as:
void Server::connect(const StringArray, const KeyValueMap) throw(std::invalid_argument,std::out_of_range)
typedef std::map Server::KeyValueMap
typedef std::vector Server::StringArray
how do i call that function in C++. The std::map and std::vector in my compiler (VS 2005) has different functions listing that the one in the dll. For example, from the depends.exe output:
std::map // KeyValueMap - del, empty, get, has_1key,set
std::vector // StringArray - add, capacity, clear, get, isEMPTY, reserve, set, size
Any advice/strategy on how i should solve this? Is it possible to simply instantiate the class like the Java example?
If you are trying to use VS 2005 to try and interface with a DLL that is built using VS2008, your attempts will be mostly doomed unless you can use a plain C interface. Given your description, this is not the case; The runtime libraries differ between VS2005 and VS2008 so there is little chance that the object layout has stayed the same between compilers. The 'something from Dinkumware' that you're referring to is most likely the C++ standard library as ISTR that Microsoft uses the Dinkumware one.
With your above example you're also missing several important pieces of information - the types you describe (Server::StringArray and Server::KeyValueMap) are standard library containers. OK fine, but standard library containers of what? These containers are templates and unless you know the exact types these templates have been instantiated with, you're a little stuck.
Is this DLL intended to be called from C++ at all? The fact that it export a JNI interface suggests that it might not be in the first place. Does it export any other public symbols apart from those that are of the format _Java_...?
Of course if there is no other way in and you must use C++ instead of Java, you might want to look into embedding a JVM into your C++ app and use that to call through to the C++ dll. It's not what I'd call an elegant solution but it might well work.
I don't quite understand the use of C++ standard library data types here. How can Java code provide a std::map argument? Are the arguments you pass in always just "opaque" values you would get as output from a previous call to the library? That's the only way you're going to be able to make it work from code under a different runtime.
Anyway...
When you make a JNI module, you run javah.exe and it generates a header file with declarations like:
JNIEXPORT void JNICALL Java_Native_HelloWorld(JNIEnv *, jobject);
Do you have any such header file for the module?
These symbols are exported as extern "C" if I recall correctly, so if you can get the correct signatures, you should have no issues with name mangling or incompatible memory allocators, etc..
The "#20" at the end of the method signature means that the function is declared "stdcall" and that 20 bytes are put on the stack when the function is called. All these methods should start with a JNIEnv* and a jobject, these will total 8 bytes I believe, on a 32-bit environment, so that leaves 12 bytes of parameters you will need to know in order to generate a correct function prototype.
Once you figure out what the parameters are, you can generate something like this:
typedef void (__stdcall *X)(JNIEnv *, jobject, jint i, jboolean b);
Then, you can cast the result of GetProcAddress to an X and call it from your C++ code.
X x = (X)GetProcAddress(module, "name");
if (x) x(params...);
Unfortunately, what you have doesn't quite look like what I have seen in the past. I am used to having to deal with Java data types from C/C++ code, but it looks like this module is dealing with C++ data types in Java code, so I don't know how relevant any of my experience is. Hopefully this is some help, at least.

VS2008 internal compiler error

I'm consistently running into an internal compiler error while attempting to switch from MSVC6 to MSVC 2008. After much work commenting out different parts of the program, I've traced the error to two lines of code in two different CPP files. Both of these CPP files compile successfully, yet somehow have an effect on whether or not the error manifests in other files.
Both of those lines involve instantianting several complex, nested templates. They also appear to be the only places in the app that use an abstract class as one of the template parameters. That said, I'm far from certain that the issue involves either abstract classes or templates, it's just the most obvious thing I've noticed. I can't even be sure that these lines are significant at all. Here's what they look like, though:
m_phDSAttributes = new SObjDict<RWCString, SIDataSource>(&RWCString::hash);
So we've got SObjDict, a templatized dictionary class, SIDataSource, an abstract interface, and the parameter is a pointer to a static member function of RWCString.
I've been playing around with the code some, and I can occasionally get the error to move from one CPP file to another (for instance, I changed a bunch of template declarations from using class to typename), but I can't find any rhyme or reason to it.
I'm at a loss as to how to debug this issue further. The exact error output by the compiler (with the name of my source file changed) is below. There is no mention of it anywhere on the internet. I'm pretty desperate for any advice on how to proceed. I don't expect someone to say "oh, you just need to do XYZ", but a pointer on how to debug this sort of issue would be greatly appreciated.
1>d:\Dev\webapi.cpp : fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c', line 5905)
The trick seems to be disabling precompiled headers. I have no idea why that solves the problem, and it's very unfortunate since my build time for the affected project has gone from less than 30 secs to nearly 5 minutes, but at least I can progress forward.
It's a reasonable bet to assume that p2symtab.c is (part of) the symbol table code. This would immediately explain how the upgrade caused it; this code has been rewritten. (Remember the 255 character length warnings of VC6?)
In this case, there is no new entry in the symbol table, so it's likely a lookup in the symbol table failing spectactularly. It would be interesting to see if the context in which th name lookup happens affects the result. For instance, what happens if you change the code to
typedef SObjDict<RWCString, SIDataSource> SObjDict_RWCString_SIDataSource;
m_phDSAttributes = new SObjDict_RWCString_SIDataSource(&RWCString::hash);
This will force another symbol table entry to be created, for SObjDict_RWCString_SIDataSource. This entry is sort of a symbolic link to the template instantiation. The new name can (and must) be looked up on its own.
Start breaking it down into smaller parts. My first guess is the pointer to the static function is going to be the problem. Can you make a dummy non-template class with the same parameter in the constructor? Does it compile if you don't use an abstract class in the template?
Looks like I'm sending you in the wrong direction, the following compiles fine in 2008:
class thing {
public:
static void hash( short sht ) {
}
void hash( long lng ) {
}
};
class thing2 {
public:
thing2( void (short ) ){}
};
int _tmain(int argc, _TCHAR* argv[])
{
thing2* t = new thing2( &thing::hash );
delete t;
return 0;
}
The principle remains though, remove/replace complex elements until you have code that compiles and you'll know what is causing the problem.
fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c
i also observed the same error when i try to build my vs 2005 code to vs 2008. but it happen till i have not installed Service pack of VS 2008...
have you installed Service pack... i think this will resolved your issue....
This typically happens with template instantiation. Unfortunately it could be caused by many things, but 99% of the time your code is subtly invoking undefined behavior.