C++/CLI project - visual-studio

When I created a new project Visual Studio 2012 created three files that I'm interested in: Stdafx.h, MyProj.h and MyProj.cpp. In MyProj.h Visual Studio created a "ref class" but I was never able to get the project to compile with the ref class there. I moved the ref class to the MyProj.cpp file, and the project now compiles fine. Why would a "ref class" be in the .h file instead of the .cpp file?

You have to understand the way C++ code is compiled and linked. It is very different from the languages you are used to, Java and C#. C++ doesn't have a standard way to break up your code into modules. Every source code file is compiled separately and produces an object file. Then they get glued together by the linker to make a program.
So if you have two source code files that use your class then they need to know what that class looks like. You do so by putting the declaration of the class in a .h file. Boilerplate is then to put the implementation of the class members in a .cpp file.
Which is what the project template gave you, a ref class in the .h file, ready for you to add member declarations to. And an empty .cpp file, ready for you to put the member definitions into.
This actually isn't that necessary anymore in C++/CLI because it is a language that actually does have modules. You know them from C#, called assemblies. And if other code, written in a different language, needs to know what the class looks like then you add a reference to the assembly. The compiler reads the class declaration from the metadata in the assembly, no .h file needed. But you'll still need a .h file if you have two .cpp files that get linked into a single assembly.
In general you'll want to pick up a introductory book about C++ programming. You'll need to know some of the basics to make effective use of C++/CLI. Such a book will certainly talk about header files and show how you split the declaration and implementation.

It's the same reason type definitions go into header files in normal C++: To help you keep definitions in agreement between all source files.
Header files are basically automated copy+paste, that guarantees you don't forget to change one of the copies.
(If different files ever start using different definitions for the same type, you violate the One Definition Rule, and the language gives no limitations on the bad things that can start to happen.)

Related

Correct way to use multiple .IDL (MIDL) files within a single "Windows Runtime Component C++/WinRT" project

Visual Studio 2019. Windows Runtime Component C++/WinRT project.
How do I follow and implement the recommendation: "We recommend that you declare each runtime class in its own Interface Definition Language (IDL) (.idl) file, in order to optimize build performance when you edit an IDL file, and for logical correspondence of an IDL file to its generated source code files. Visual Studio merges all of the resulting .winmd files into a single file with the same name as the root namespace. That final .winmd file will be the one that the consumers of your component will reference."
https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/author-apis
Within the same project I can add a second (third and so on) .IDL file using Project->Add New Item->Midl File (.idl). This seems to work ok?! I then manually add associated .h and .cpp files for each .IDL file. Build to generate stub files then manually copy and "fill in" these files before a final build which is successful. In this way I have a single IDL file per runtime class with its associated headers and implementation files including any other files (c++ .h and .cpp files) needed for the implementation. As I need to add functionality to the interface I just edit the IDL file, rebuild and add functionality to the header and implementation C++ files.
Is this what was recommended?!?
When I add the .IDL file and then manually add an associated .h and .cpp they do not appear "under" the .IDL file as the original ones did when I created the new project. Is this just a visual nicety of Solution Explorer OR is this indicating that I have something wrong?!?
I plan to have multiple "C++/WinRT WRC" projects (one for each namespace, each consisting of multiple runtimeclass interfaces with separate .IDL/.h/.cpp files as described above. Then I reference all of the projects (project to project) in my single C#/UWP App.
I am actually trying to implement a user interface to allow me to utilise a large code base of math/engineering C++ classes that implement a very specific & proprietary type of electronic circuit simulation already existing and programmed in C++ and compiled as a console app. The user data in and out is relatively small compared to the processing that takes place to generate the output.
It looks like you are handling the idl files correctly and that behavior is the same as I experienced when just adding a new Midl file directly.
If you like the look of having the .h and .cpp files "under" the .idl file in the tree you can try adding a new View Model instead of a new Midl file. This will create the .idl/.h/.cpp files all with the same name and place the .h and .cpp files visually under the Midl file. The idl template you get this way is for a basic runtime class.
When creating a new Windows Runtime Component, the .idl and the .h are usually grouped under the .cpp, not the .idl, but whatever your preference. There isn't a template to add a Runtime Class, which is pretty dumb. One fix for this could be as follows:
This is not a perfect solution, but is the easiest. Create a new Windows Runtime Component. Open Project>Export Template. Select Export Item. Select the Runtime Class under the new component. Export with Automatic Import option checked. Save your project and exit VS. Open your project. You can now add a fully templated Windows Runtime Class by simply adding item>Runtime Class. However, there will still be no dependencies (there may be a tool for custom nesting, but not in community as far as I can see). To fix this, after adding the files, save the project. Edit the project file (use notepad++ or even unload project, edit) and add the property <DependentUpon>Runtime Class.idl</DependentUpon> between your .cpp and .h file delimiters. Save the project file and reload. Probably want to do this in batches.
The alternative is to write a .vsix to either add the files and edit the project file, or have a right click command that runs on a .cpp and edits the project file, adding the DependentUpon directive. I can't find a 2022 functional .vsix for this. I will post one if I make one.

How can you identify which project produces a particular dll?

Is there anyway within Visual Studio / TFS to identify which project produces which dll?
I'm aware you can look under a particular project's properties and see what the name of the dll is, but in the circumstance where you have loads and loads of projects this doesn't seem very efficient.
I've got the situation where I've got a project that references a dll, which includes a method I want to examine, but I don't know what project produces this dll.
Unfortunately, no. The only way I know is that you may could use a decompile extension. (Strongly not recommend to use) Through the source code after decompile, you can view namespace and judge which project produces the dll. (Under normal circumstances)
And you may also have to face some problems such as:
Legal issues
Need to pay for the extension
Only work for C#/.Net
The source code may be confusion and not standard
This should be a one time activity, you can go ahead and take a look into the project file, in case of C# project the csproj file.
If you do not want to do it opening each file, then i would say write a small tool to read all the project files and look for the name.
BTW, this will be different for different projects, and you need to find out the proper location to look.

Interop assembly not found in F# solution

F# newbie here, spent many painful hours trying to resolve the errors with a simple piece of code from MSDN F# tutorial.
#r "Microsoft.Office.Interop.Excel.dll"
// fails with invalid/not found errors
#r "Microsoft.Office.Interop.Excel" // works like a charm.
Any F# gurus know why?
"Microsoft.Office.Interop.Excel.dll" is the name of a file (inferred, because of the .dll suffix). When you supply a file name, #r will look for that file in the file system. Since you didn't supply a path, it'll look in your present working directory. Most likely, "Microsoft.Office.Interop.Excel.dll" isn't in your working directory. This explains why the first example fails.
"Microsoft.Office.Interop.Excel", on the other hand, is inferred to be the name of an assembly (because there's no file extension). Assemblies are libraries, and are normally distributed in .dll files. They don't have to, though; they can, for example, be dynamically emitted at run-time. Additionally, a .dll file can technically contain more than a single assembly, although I've never seen this in the wild. The most normal case is that a .dll file contains a single assembly, and that the name of the file corresponds to the name of the assembly.
When you request to load an assembly, the .NET assembly loader (called Fusion) starts looking for an assembly with the requested identity. It'll start looking in the Global Assembly Cache, and my guess is that it finds the "Microsoft.Office.Interop.Excel" assembly there. This explains why the second example succeeds.

Qt, CMake, Visual Studio and Q_OBJECT in cpp files

I'm developing a large project using Qt 4.6, CMake 2.8 and Visual Studio 2008 for the Windows platform.
As far the build system goes, it's all standard stuff: I'm using CMake's QT4_WRAP_CPP macro to generate moc files from header files, which are then linked into the final executable in the add_executable command. Everything is working as expected.
The only restriction with this setup is that I can't define widgets or helper using Q_OBJECT in .cpp files. This would be very convenient for small, context-specific helpers classes that should appear right next to where they're used.
I tried to pass the whole list of source files (both .h and .cpp) to QT4_WRAP_CPP, instead of just the header files, but that doesn't work (linking fails because some moc-related symbols are undefined).
I think the problem is that, for a given pair of files foo.h and foo.cpp, the QT4_WRAP_CPP macro will generate the same moc file (moc_foo.cxx) in the same directory, and obviously that means the first file will be overwritten by the second one, and as a result symbols will be missing at link-time.
Is there a way to fix or work around that problem? For instance, I tried to add a specific rule for foo.cpp of the form
QT4_GENERATE_MOC(directory/foo.cpp directory/foo.moc)
and then add
#include "foo.moc"
at the end of foo.cpp. I think this ought to work, but alas Visual Studio only allows one build rule per file, and .cpp files already have a build rule (compilation to object file), so this approach doesn't work, at least with Visual Studio.
Another idea that I had was to create a new macro, say QT4_WRAP_CPP_WITH_PREFIX, based on QT4_WRAP_CPP (which is defined in share/cmake-2.8/Modules/Qt4Macros.cmake), that would take an additional prefix argument and would add this prefix to the generated moc files. That way, I would call QT4_WRAP_CPP_WITH_PREFIX twice, once for .h files and once for .cpp files, with different prefixes. What I just dislike about this approach is that I'd be messing with the internals of CMake's Qt support, instead of using the public API.
Any better idea?
Recent versions of CMake have "automoc" which worked like a charm for me:
http://blogs.kde.org/2011/11/01/cool-new-stuff-cmake-286-automoc
Simply add in the CMakeLists.txt:
set(CMAKE_AUTOMOC TRUE)
and then in the cpp (e.g. example.cpp) file:
#include "example.moc"
(the *.moc must match the cpp file's name).
Referring to the documentation "Using the MOC" (http://doc.qt.nokia.com/4.1/moc.html), you'd only need to import "foo.moc" at the end of your implementation file. As you can not tweak the build rules correspondingly, try to export a .pro file and apply the build rule as suggested by the nokia document.

Create static library from multiple .h/.cpp files (Visual Studio 2005)?

I'm trying to create a static library using Visual Studio 2005, consisting of multiple header and source files, for example:
A->B, A->C, A->D
B->E
(A->B = B is #include-d in A)
I managed to compile a static library by following the MSDN tutorial and put all the files in a project file in Visual Studio, and compiled a .lib. The problem is, I only want others to have access to one header file (A), and not the others, but because A includes the other files, after I have compiled the library and tried to use this in another project, when I only include the static library and header file from A, it says it can't find the header files for B, C, D and E. Is there a way to solve this issue?
One method (not the most elegant and simple method) I thought of is to put all the codes into one set of header/source files, but that's a lot of work and can get quite tricky...
Not without refactoring.
When creating libraries I like to arrange my header libraries into public and private headers. You can have a private header include a public header but not vice versa.
You're going to need to clean up your header files to cleanly separate the public and private parts of your API.
Unfortunately, without knowing why your header files are structured the way they are, I can't offer more specific advice.
When designing a library, it's important to separate the interface you want to expose from
the implementation of your library.
Just create a header file with the stuff you want to expose to users of your library, or e.g. just don't have A include the other header files.

Resources