VARIANT members not resolved in C++ OLE automation application (Eclipse IDE) - c++

I'm developing a C++ application that reads and writes to Excel using OLE automation (code based on this: http://support.microsoft.com/kb/216686).
The application has been up and running just fine when I was using VS2010. However recently I decided to move to Eclipse, and all of a sudden the compiler (CL) won't recognize the structure of the VARIANT struct (doc: http://msdn.microsoft.com/en-us/library/aa908601.aspx). For instance in this piece of code:
VARIANT tmp;
tmp.vt = VT_R4;
tmp.fltVal = 5.0f;
tmp.fltVal cannot be resolved in Eclipse (while it works just fine in VS2010, and every code sample I've seen online). The only way to get Eclipse to stop displaying an error is to replace the last two lines with:
tmp.n1.n2.vt = VT_R4;
tmp.n1.n2.n3.fltVal = 5.0f;
Same goes for tmp.parray and all other members of VARIANT.
Has anyone come across this before ? What am I missing here ?
PS: No, replacing the code everywhere is not exactly an option

Related

Can't find COM object from C++, although Guid it's registered

First of all happy new year to everyone, hope you're doing well!
I'm working on a C++ project in which I need to call a C# DLL I created following the first answer of this post. Once I have the DLL, I need to call it from Qt, so by using dumpcpp and the .tlb file generated by regasm, I managed to get the .cpp and .h files to use my classes. Just as a reference, the namespace of the classes is Wrapper, and the main class is Device with guid {DD4A4896-C105-4C60-839B-B18C99C8FE15}.
Once I have the generated files to use the DLL, if I try to create a Wrapper:: Device instance on Qt, I get the following error:
QAxBase::setControl: requested control {dd4a4896-c105-4c60-839b-b18c99c8fe15} could not be instantiated
QAxBase::qt_metacall: Object is not initialized, or initialization failed
It doesn't give any more information, so I tried to check if the guid was stored on the system registry (I used the regasm command explained on the previously quoted post, and It said that it was successful, but you never know). Opening Registry editor and searching for the Guid revealed that it's present at: Computer\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{DD4A4896-C105-4C60-839B-B18C99C8FE15}, which, as far as I know, is the right route for these guids, and it points to the right DLL.
I though It may be due to some kind ActiveQt problem, and as the previously quoted post explained how to use that DLL from VS C++, I decided to give it a try, using this as an another reference. I've finished with this code, which is supposed to create an instance of my Device object
#include <iostream>
#include <atlstr.h>
#import "C:\Users\javie\Documents\Wrapper\Wrapper\bin\x86\Release\netstandard2.0\Wrapper.tlb" named_guids raw_interfaces_only
inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); };
int main()
{
try
{
TESTHR(CoInitialize(0));
Wrapper::IDevicePtr devPtr = nullptr;
TESTHR(devPtr.CreateInstance("{DD4A4896-C105-4c60-839B-B18C99C8FE15}"));
}
catch (const _com_error& e)
{
CStringW out;
out.Format(L"Exception occurred. HR = %lx, error = %s", e.Error(), e.ErrorMessage());
MessageBoxW(NULL, out, L"Error", MB_OK);
}
CoUninitialize();// Uninitialize COM
std::cout << "Hello World!\n";
}
However, this doesn't work either, the createInstance method throws an exception of Class not registered and HR=80040154. Again, according to Registry editor, the class is registered, so I don't understand the error. I've also tried with devPtr.CreateInstance("Wrapper.Device"), devPtr.CreateInstance("Wrapper::Device") or `devPtr.CreateInstance("Wrapper::CLSID_Device") as the links I posted suggest, but in those cases I get another exception with HR=800401f3 and message Invalid class string.
It doesn't matter whether VS or Qt Creator are opened as administrator or not, I get the exact same error.
I have run out of ideas, and I really need to be able to use that DLL from Qt using the files generated by dumpcpp.
Does any one know what could be happening? It feels quite strange to me.
If your C++ application is 64-bit, that's the answer right there, because your C# component is 32-bit (or MSIL but registered to the 32-bit hive). In situations like these, a simple test using VBScript is always useful.
Write a simple VB Script (test.vbs)
Dim obj
Set obj = CreateObject("Wrapper.Device") ' or whatever your ProgID is
MsgBox TypeName(obj)
Now, run this macro 2 ways: with 32-bit and 64-bit versions of VBScript:
32-bit > c:\windows\SysWow64\cscript.exe test.vbs
64-bit > c:\windows\system32\cscript.exe test.vbs
This is assuming your C# component is dispatch compatible. If it's not, then it will still give you differing results that you can use to debug.
Assuming automation/IDispatch compatible, one will work and one won't if you have registered your component correctly.
Have you registered correctly? When I use regasm, I always use the the switches /tlb /codebase when registering the C# component for COM.
Ok, in case someone find the same error, I'll explain the solution I found.
The problem was that in my case, the C# class I developed depended on another 32 bits dll which was not registered on my PC. Once I registered the other dll, everything worked fine.
I don't know why VS kept telling me that the class was not registered when my class itselft was registered, it was one of its dependencies that wasn't registered.
Anyway, I discovered this thanks to Joseph's comments, so thanks a lot for your help.

Aspose.PDF Triggers Breakpoint

I implemented Aspose.Cells and Aspose.PDF into our companies existing application.
While I had some trouble with this (mostly caused by the fact that I tried to implement both APIs into the exat same file which was a bad idea)
I figured out how to make it work more or less.
My Problem now is while Aspose.Cells works perfectly fine and doesn't seem to have any unusual behavior Aspose.PDF already struggles with setting the license and even when I eventually got this to work I can't even initiate a Aspose::Pdf::Document.
So the first totally unusual thing is the way I had to set the License in the Example code given with the Aspose Package and in the official resources the license is set like this.
auto lic = System::MakeObject<Aspose::Pdf::License>();
lic->SetlLicense("c:\\Foo\fooproj\\Aspose.Total.C++.lic");
This code won't run on my machine and cause the error.
Rough Translation
food.exe triggered a breakpoint
Original
food.exe Hat einen Haltepunkt ausgelöst
The same happens when I initialise a System::String with a emtpy constructor like this.
auto lic = System::MakeObject<Aspose::Pdf::License>();
System::String str;
str.FromUtf8("C:\\foo\fooproj\\Aspose.Total.C++.lic");
lic->SetLicense(str);
BUT if I initialise the System::String with an empty String in the first place setting the license seems to work just fine so this works.
auto lic = System::MakeObject<Aspose::Pdf::License>();
System::String str(u"");
str.FromUtf8("C:\\Projekte\\Aspose\\Lizens\\Aspose.Total.C++.lic");
lic->SetLicense(str);
If this code above works and I try to make an object from Aspose::Pdf::Document this will crash.
void Aspose_pdf::helloWorld()
{
auto doc = System::MakeObject<Aspose::Pdf::Document>();
.....
.....
}
I actually have no idea what's going on. I am not using any using namespace commands at the moment.
Would be greate if someone had an idea how to fix this.
Edit:
The error occures exactly in smart_ptr.h in the following function.
typename std::enable_if<!IsSmartPtr<T>::value, SmartPtr<T> >::type MakeObject(Args&&... args)
{
System::Detail::OwnNextObject ownershipSentry;
T *const object = ::new T(std::forward<Args>(args)...);
ownershipSentry.CreatedSuccessfully(object);
return SmartPtr<T>(object);
}
in the second line so T *const object = ::new T(std::forward<Args>(args)...);
is "causing" the error or atleast here the error will ne triggered.
Edit2:
Here you will find a simple example of how my code looks in general.
I Started with implementing Aspose.Pdf into my Programm so I edited my
Additional Library directories,additional dependencies, additional include directories,preprozessor definitions and my stacksize to fit these settings given in the Aspose.Pdf examples.
After this I created my Aspose_Pdf class and tested it. worked perferctly so far.
After this I made the same edits to fit Aspose.Cells aswell. Also I created a class Aspose_Cells and tested it. While this worked now my Aspose_Pdf class stoped working. After a little time passed I managed to atleast get the License Activation for Aspose_Pdf to work from this point on I had the problems described above.
Additional Dependencies:
...
Aspose.PDF_vc141x64d.lib
aspose_cpp_vc141x64d.lib
Aspose.Cells.lib
Additional Librariedirectories:
...
..\Aspose\Aspose.PDF\lib\Debug
..\Aspose\Aspose.Cells\lib64
additional Includedirectories
...
..\Aspose\Aspose.PDF\lib\Debug
..\Aspose\Aspose.PDF\include\asposecpplib
..\Aspose\Aspose.PDF\include\Aspose.Pdf.Cpp
..\Aspose\Aspose.Cells\Include
..\Aspose\Aspose.Cells\Include\icu\include
..\Aspose\Aspose.Cells\Include\boost
I've never heard about Aspose.Pdf neither I know how does System::MakeObject< work. But for me it looks that all the code might be simplified to next:
Aspose::Pdf::License^ lic = gcnew Aspose::Pdf::License();
System::String^ str = "C:\\foo\\fooproj\\Aspose.Total.C++.lic";
lic->SetLicense(str);
When it comes to Pdf.Document the initialization might look like this:
Aspose::Pdf::Document^ doc = gcnew Aspose::Pdf::Document();

Building RakNet C# Wrapper with Swig, get an annoying error at build

I know I should post this on the official RakNet forum, but I actually have, but it seems to be dead as hell.
The reason why I'm asking here is because I have no idea of C++, I'm a game developer and we're using Unity3D/C# to develop our new game, it's going to be Multiplayer and as RakNet was Open Sourced I wanted to give it a try.
So, here we go, this is the error log:
raknet_wrap.cxx(15441): error C2558: class 'RakNet::ReliabilityLayer' : no copy constructor available or copy constructor is declared 'explicit'
And the line where the error is is this:
jresult = new ReliabilityLayer((const ReliabilityLayer &)result);
Full function:
SWIGEXPORT void * SWIGSTDCALL CSharp_RakPeer_RemoteSystemStruct_reliabilityLayer_get(void * jarg1) {
void * jresult ;
RakNet::RakPeer::RemoteSystemStruct *arg1 = (RakNet::RakPeer::RemoteSystemStruct *) 0 ;
ReliabilityLayer result;
arg1 = (RakNet::RakPeer::RemoteSystemStruct *)jarg1;
result = ((arg1)->reliabilityLayer);
jresult = new ReliabilityLayer((const ReliabilityLayer &)result);
return jresult;
}
Can someone tell me why is it not working and explain it for a completely new person to C++ so I can understand the error?
(Edit) Going to also provide the ReliabilityLayer class! Here it is: http://pastebin.com/qTXedJFw
So I finally managed to build the RakNet C# DLL of the newest RakNet version.
And, as I don't want anybody with no experience on C++ to go through the madness I did through, I'm just sharing the DLL for easy use. Just import it to your project and start using it.
Here it is: https://drive.google.com/file/d/0BwuOJwLuDZfnM29DTFlLTWZWOXc/view?usp=sharing
OK to whoever is watching this and doesn't have a successful answer.
This is clearly a compiler bug in MSVC 2013 (that's what I tried).
SWIG generates the file 'RakNet_wrap.cxx' with the following line:
jresult = new ReliabilityLayer((const ReliabilityLayer &)result);
The quickest way around it is to edit this line so that it reads:
jresult = new ReliabilityLayer(result);
and hence the casting becomes implicit instead of explicit and MSVC 2013 accepts this.
The only problem is that when you hit Build, SWIG will overwrite this file and introduce the error again. So just remove the SWIG prebuild step (Alt+F7->Build Events->Pre-Build Event remove the PreBuild.bat from the command line) and build again. Now it will successfully compile and link as it should.
Don't forget to put the PreBuild.bat file again if you need to modify the source code and run SWIG again!
Also use SWIG 2.0.12; the latest version I tried (3.0.5); generates broken C# code (undefined HandleRef and IntPtr because System.Runtime.InteropServices is not either explicit nor imported via 'using' keyword).
I've raised a ticket to the SWIG project about this: https://github.com/swig/swig/issues/433

Embedding Lua to C++ and wxWidgets using Eclipse IDE

I am new to Lua so I am sorry if this is rather an easy question but it is driving me nuts. In my previous thread A simple query on calling Lua 5.2 from C++ I have used an easy C++ code to embed Lua in it. Things worked well but when I transfer that concept to a more complex project, the same code does not work. I have checked many sources but could not find a solution.
Here is my code:
#include "External/include/lua.hpp"
lua_State *luastate =NULL;
IMPLEMENT_APP(ScienceSuitApp);
bool ScienceSuitApp::OnInit()
{
luastate=luaL_newstate();
luaL_openlibs(luastate);
ScienceSuitFrame* frame = new ScienceSuitFrame(0L);
frame->Show();
return true;
}
Now when I try to compile the code, I am getting invalid arguments error for the luaL_openlibs(luastate) line. The error that the compiler gives:
Invalid arguments '
Candidates are:
void luaL_openlibs(*)
' ScienceSuitApp.cpp /ScienceLab line 33 Semantic Error
This is actually happening whenever I call a Lua function such as luaL_dostring etc.. which takes lua_State as parameter. By the way, I am using Eclipse as IDE and wxWidgets as GUI if that should give a clue. Any my configuration for this set up is:
I "think" I have solved the problem. It stems from the fact that Eclipse throws a "semantic error" and not a "syntax error". Therefore, I followed the advice from Eclipse CDT shows semantic errors, but compilation is ok. But now my question is what does it have to do with Indexing in Eclipse IDT? It feels like I am using Eclipse without knowing any of its internals.

Why do I receive a SIGSEGV signal while using the Aria robotics API?

I am using the Aria C++ programming libs for mobile robots (http://robots.mobilerobots.com/wiki/ARIA). I am new to this API so I wanted to start with a simple action class derived from ArAction. Now I tried to develop a small test program (an ArAction) in order to
control a simulated p3dx robot via MobileSim. Development takes place under Ubuntu 10.10, using gcc 4.4.5. Making (compiling) my code works fine, without errors. I can also set the desired speed for example in my ArAction's fire() method, and the simulation is also working as desired.
But, unfortunately, I can't use the ArRobot object attached to the ArAction I am overriding. The problem is that none of the member functions of the ArRobot object seems to work. For example, calling getVel() or getCompass() always returns a zero value. And when I call the hasFrontBumpers() method the program even crashes with the error message "Aria: Received signal 'SIGSEGV'. Exiting.". As soon as I remove this method call and recompile the error is also gone again...
Here is the relevant code that leads to the crash:
ArActionDesired * forward::fire(ArActionDesired d)
{
desiredState.reset();
ArRobot *r = getRobot();
if(r == NULL)
{
printf("ArRobot = NULL\n");
deactivate();
return &desiredState;
}
printf("ok, ArRobot is not NULL, check for bumpers...\n");
r->hasFrontBumpers(); // <-- this leads to the SIGSEV-based "crash"
return &desiredState;
}
Any ideas what I am missing here -- is it a problem with my coding, or with the simulation environment? Thanks in advance for your help!
Kind regards, Matthias
ok, found it out now -- for the records: the Aria libs in version 2.7.2 are based on gcc-3 and libstdc++ 5, but Ubuntu 10.10 (which I am using) is shipped with gcc-4 and libstdc++ 6 per default. So I had to manually install the older versions of both packages, now my code is running fine...
cheers!
Calling hasFrontBumpers() for a p3dx from the fire() works fine for me on a similar Linux platform. If something is wrong, it is not in this method but in the initialization of the system. A reason for the non-moving robot could be that robot.enableMotors() hasn't been called.