rss

C++

Web service for device (WS4D) and using make, cmake with Integrated Development Environments (IDEs) on Linux

by on Dec.16, 2011, under C++, Desktop, Linux

WS4D-gSOAP is a framework to deploy web services on multiple environments (computers, embedded devices, phones…) without having to rewrite code. More introduction information can be found in this post. The downside for WS4D is that the build system is based on cmake, and it’s a bit complicated to use. I have since managed to successfully build the stack from source (there’s no binary distribution). But I ran into numerous problems during my time getting familiar with the stack. Namely following the tutorial.

Even for such a simple task of copying and pasting code from the tutorial (The Air Conditioner tutorial), I did not succeed. The client and device doesn’t seem to be able to communicate with each other. Even though the tutorial have been kind enough to include logging code (send, received and memory allocations), I’m still unable to figure out where the problem lies. And that’s when I think I’m forced to perform debugging on the project. That leads to a big problem: what am I supposed to use to debug this?

So I tried to install Code Blocks, but it doesn’t support cmake projects, it couldn’t import the CMakeList.txt. Then reading through several articles revealed Eclipse to be a pretty good gdb front-end, I installed it, and have successfully imported the project, but I was hit with several problems:

  • I couldn’t build the project, Eclipse’s project structure was make-based, not cmake-based, trying to ‘make all’ or ‘make clean’ with Eclipse obviously would generate errors
  • Editing  the code is an eyesore because Eclipse doesn’t seem to be able to recognize include and libraries directories even after I added them manually in project properties.
After several more hours of analyzing WS4D-gSOAP documentation (not really helpful, they are only related to build and run with command line), cmake (wiki pages after wiki pages with no structure between pages and in articles), Eclipse and Code Blocks’ documentation on make projects; I finally realized the right way to do this: cmake supports generating make-based projects for both Code Blocks and Eclipse, and it’s as simple as this:
  1. Go to the directory where you would normally run cmake to build your project from the command line
  2. Perform

    cmake -G"Eclipse CDT4 - Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../certi_src
    cmake . -G "CodeBlocks - Unix Makefiles"
  3. Import

    The project directory
    ProjectName.cbp file
You can now work with the project normally within your preferred IDE
Leave a Comment :, , , , , , , , , more...

Why specifying the call type when performing P/Invoke is important

by on May.01, 2011, under C Sharp, C++, Development

I was working on a C# project that required interaction between unmanaged and managed code. It’s nothing complex, just calling various functions in a DLL through a wrapper class, then I hit this exception:

A call to PInvoke function 'TestLPRLib!EvAPI.EvLicensePlateReg::evLPROpen' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

Strange thing is, this “stack unbalanced” exception only pop up when running in debug mode, the application still work just fine without debugging, but leave bugs in applications is not my habit, so I decided to reach out to Google. The unmanaged code used __declspec(dllexport) to specify exported functions, internet forums suggested this exception is caused by the difference in calling convention.

So, I changed the unmanaged code from

extern "C" __declspec(dllexport) int evLPROpen(int width, int height, int widthStep, int depth = 8, int channel = 3);

to

extern "C" __declspec(dllexport) int __cdecl evLPROpen(int width, int height, int widthStep, int depth = 8, int channel = 3);

And the wrapper from

[DllImport("LicensePlateRecognitionLib.dll")]
public static extern int evLPROpen(int width, int height, int widthStep, int depth, int channel);

to

[DllImport("LicensePlateRecognitionLib.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int evLPROpen(int width, int height, int widthStep, int depth, int channel);

(using the clear stack by caller convention), and the exception goes away. By default, .NET assumes you use __stdcall, but I didn’t have much success trying this :)

Leave a Comment :, , , , more...

preg_match() in action

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post to let me know! :)