Linking error when referencing a C++/CLI .exe project - visual-c++

I'm using VS2010 and in my solution one of my C++/CLI projects references the other. But it can only link correctly when the project being referenced is compiled as a Static Lib.
I read all over that in managed .NET languages, .EXEs, libs and .dlls are the same thing, with a single flag or something like that as difference. Being like that, I can't figure out why I have all these linking errors, since it shouldn't matter how I compile my project.
Well, probably I'm assuming something wrong. If so, how can I reference a .exe project in an other .exe project so I can use the same classes and methods without having to recompile it.
Thanks in advance,
Theo

While referencing an EXE project and loading it at runtime as though it were a DLL is okay for pure managed code, that is not going to work out well for a C++/CLI project. The CRT won't be initialized correctly, there is no DllMain() entry point that will run.
You'll need to create a DLL, use the CLR Class Library project template.
What ever compile or link errors you'll get after that might be secondary. Make sure you quote them in your next question, error messages were designed to tell you what is wrong.

Right click on your project and choose "Add reference..." in the menu.
PS: can you show the linker error messages?

Related

How are project interdependencies managed in MS Visual C++?

Probably a pretty fundamental question. When developing a single-project-solution in MSVC++ everything makes a lot of sense, every file is visible to the compiler. When moving to a multiple project solution, none of the interface elements governing project dependence seem to make sense (coming from a .net background.)
For starters it appears setting up project dependencies with that terminology seems to only imply what order the projects are compiled in. There is no more function attached to the definition and addressing objects or methods of one project from another will not work. #including the headers of the dependency doesn't seem to work either, so the dependent project cannot see the files of its dependency. Copying a link of a header from one project to another doesn't work either, where for two projects under the 'Header Files' section, the same file is referenced in both locations. Even with this header references do not work and the files are unconnected. The only way of creating a functional dependency is to add the dependency's paths to the linker/compiler search path of the dependent or worse, simply copying the files of one project to another.
Either I'm missing something or the .NET Visual Studio IDEs have succeeded at what the VC++ IDE has badly failed at.
Edit:
For the sake of asking a specific question, take the following steps for creating a solution in VC++ and I ask if the missing step(s) can be filled in:
Create empty DLL project inside new solution.
Create method in DLL project and compile.
Create new empty executable project.
Create main method in new project.
...
Have main method call function in DLL project.
Preferably fill in the missing step(s) with the most most modern/industry standard/best practice method that best maintains project modularity as intended.
From this I would expect to independently be able to extrapolate and create classes, enumerations etc. in the DLL class and access them all in the executable project, so long as I can find out how this is intended to be done.
In step 2, as per the usual C++ rules, declare the method in the header. Read up on __declspec(DllExport) since the default is that methods are internal to the DLL.
In step 5, as per the usual C++ rules, include the header. Visual C++ needs to know where the header is coming from, so you need to reference the source project. Details vary between Visual Studio versions.
In step 6, you call the method in the normal way. Since it's now declared as __declspec(DllImport), the compiler will leave it to the linker, and the linker will get it from the correct DLL.

ATL: Can't remove a method from a COM interface - ALWAYS reappears like magic

Environment: VS2008, C++ ATL COM, 64Bit, Windows 7
I'm trying to remove a method from an older COM interface. I modify the *.idl, modify the associated *.h and *.cpp implementation files and also remove it from the main project's .h file. I can search the whole project for the old method name - does not show and it compiles/links fine. However, if I then use the Object Browser to look at the compiled DLL - the dang method is still there! If I 'reference' the DLL in a .NET project - shows the method. If the .NET code attempts to use the method - it gets a memory exception (which makes sense). I can't for the life of me figure out how to modify the IDL, remove the method code and have the resulting compiled DLL be correct.
Where the heck is the method lurking and is there a different way to remove a method from an existing ATL generated COM interface? I'm stumped! Thanks!
Did you unregister the old DLL module and registered the new one? Sounds like your registry may have an inconsistent entry.
Also make sure there are no pre-compiled headers etc laying around so that when you compiler you are sure it hasn't included some old copy.
probably best is to delete the complete build directory (debug/release) before compiling just in case you missed deleting some old files.
check also the path where the .dll is loaded, you can see that in the object browser, compare that with the registry entry. maybe you did a 32bit version before?

Share source code between projects [VS2008,C++]

How can I share source code between 2 projects in MS Visual Studio 2008 (I'm programming in C++)?
In my case, I have the code for the main game project and now I want to make a simple model editor that uses the game's code, so that whenever I change/add some code in one project it will be updated in the second one.
A common method for doing this, (you'll see it everywhere in open-source packages), is to bundle all the headers into an 'include' folder and all the source into a 'source' folder.
Now in whatever project needs the code, you go to, 'Project Properties->c/c++->General->Additional Include Directories'. Then add the path to the 'include' directory. Finally, add the source/headers to your project, now both projects reference the exact same files, which are in a nice tidy shared location.
You can also build the shared code as a static library or better yet (IMO) a DLL. This involves creating a new project, and learning a little bit about the linker in VS 2008, but really nothing too complicated. This also has the advantage (in the case of a DLL) that the two projects don't re-compile the same code, but rather it is compiled once and used twice.
You can move the required classes into a separate library project and then references this from the second project. Any changes will be automatically picked up.
(I'm not a C++ developer, however the above works for C# projects, I would assume it works for C++ projects too)
You basically have two options:
Create a static library. In this, all the code in the library will be exported and visible to who ever links to this library.
Create a DLL: here, you can define what classes and methods you would like to export and use those.
Lets say you have a class called classA which is defined in classA.h and implemented in classA.cpp and you want to use this same class from two different applications (application B and application C).
Using method 1, you would create a static library by going to file->new win32 project and in the box that pops up, choose application settings and make it a "Static Library". Then in this static library you add both your classA.h and classA.cpp.
To use this static library in application B or C, goto the references and add a reference to the static library project that you just created. then include classA.h in your application (don't forget to set the additional include directories path) and you are good to go.
The approach is very similar for a DLL as well, the difference here would be that you can choose what parts of your code in the DLL are exported (ie visible to outside callers).
From an overall point of view:
With the static library approach, your code will be compiled into both the applications.
With the DLL approach, there will be just one copy of the shared code (in the DLL which will be a separate file) and this will be loaded as required.

Export Unmanaged Classes from a Visual C++ DLL?

When creating a DLL with Visual C++ 2008 I have a couple of choices. I can create a "Class Library", which I understand will actually give me a .Net Library that uses the CLI (managed) extenstion of C++.
Since I don't want that, and I assumed that I need a static .LIB file to link into another Visual C++ windows executable project, I choose instead "Win32 Project" and, on the Application Settings panel, specify a C++ (no MFC) DLL.
This will create a project with a .cpp file which is supposed to be where I define "the exported functions for the DLL application".
This doesn't seem to be what I want either. Basically, what I'm looking for is the native C++ equivalent of what would, in C# .NET be a class library assembly. I want to package some classes into a DLL, then have a .EXE project use the DLL's classes by including the DLL project header files and link with a .LIB to resolve references.
What's the usual way of doing this?
You're doing it right. What you'll need is to mark your classes with __declspec(dllexport) to make them available from outside the project. When you build the project, you'll generate both a .DLL and a .LIB.
Create a new Project
Visual C++ : Win32 : Win32 Project
Application Settings select DLL and check 'Export Symbols"
When you generate the project, it will stub out an exported class for you, typically named C{MyLib}.
You are right to make a C++ (no MFC) DLL. You can create your classes and those entry points which you define will be exported from that DLL for use by other C++ code (for example, a Win32 application written in C++).
Since C++ names get mangled automatically by the compiler to weird and wonderful values, it's not practical to export them as is if the DLL's clients are, for example, C programs. But if everything is in C++, you should be OK.
If you create some classes, you can choose to have them linked dynamically (as a DLL) but you will need an import library (created for you automatically) which contains the DLL's symbol definitions. You can also choose to link statically to your code from an application - in this case you would end up with a static library (also a .LIB) which contains the actual object code in your classes rather than symbols in a DLL.
The advantage of a DLL is, of course, that if you write several applications using your library, they can all share the DLL; with a static library, they would each contain a copy of your library code.
I think this article describes what you are trying to do:
http://www.codeproject.com/KB/mcpp/usingcppdll.aspx
Personally I also prefer exporting C functions (as opposed to C++) where I make the this pointer explicit to avoid having to care about compiler specific method name decoration and exposing compiler generated functions.

How to resolve incorrect "Ambiguous reference" from ReSharper on class inheritance?

In my project I have a class that is inherited by many other classes. We'll call it ClassBase.
public class ClassInheritFromBase : ClassBase
When ClassBase is being inherited, ReSharper throws an "Ambiguous reference" warning on the ClassBase, and anything inside the new class that inherited from ClassBase does not have IntelliSense and gets warnings that it cannot find it.
The project compiles and runs fine.
If I change the namespace ClassBase is in and then change the inheriting classes, they find it fine and ReSharper has no problem, IntelliSense works ... until it is compiled. After the compile it goes back to having the ambiguous reference warnings and everything else.
Has this been seen before and how can it be fixed? I saw an entry in JetBrains bug tracking for an issue just like this, but they closed it as unable to reproduce.
For those who still have a problem with this, (I still get it from time to time) here's the steps I did to get rid of the ambiguous reference warning in ReSharper.
First I went to all my class libraries and made sure that all references to my other class libraries had the Copy Local property set to false.
In the project where I actually got the ambiguous reference warning, I went to my bin catalog and deleted all .dll and .pdb files for all the libraries that had their own project.
After a new build, or in my case "update reference" on the .dll files in VS, the errors from Resharper were gone.
I'm using Resharper 5.1 in Visual Studio 2008 with only a reference to the dlls I'm using which is why I had to "update reference"
I'm using VS 2012 and ReSharper 7 and sometimes I found the same behavior. These are the steps that worked for me:
Clean Solution
Close Visual Studio
Go to the root folder of your solution and find a folder called _ReSharper.[Name of your solution] and delete it.
Go back to Visual Studio, open up your solution the folder gets recreated and no more "ambiguous reference" errors after that.
I've seen this bug in ReSharper 4.1. It happens when the base class is in the App_Code directory. I don't know how to fix it; it is very annoying, but the code still compiles though.
You may really have an ambiguous reference. In the project where the ambiguous reference error occurs, make sure to check in your project references. You might have the same reference twice but scoped through different namespaces. In my case there were two, but with different paths (example):
XXX.YYY.ZZZ.myassembly
ZZZ.myassembly
Make sure you don't have this kind of thing in your references.
This is a bug in ReSharper 4.1 and is fixed in one of the later nightly builds.
Download the last nightly build at
http://www.jetbrains.net/confluence/display/ReSharper/ReSharper+4.0+Nightly+Builds.
ReSharper -> Options -> General: Click # Clear Caches # button.
For me it was a matter of me not using the solution folder for caches. Changing it from the TEMP location to in the solution solved my problem.
I deleted the _ReSharper.SolutionName folder found in the root of my solution and restarted.
I was using Visual Studio 2010 with ReSharper 5.1... Clearing the cache DID NOT help (ReSharper -> menu Options -> General -> #Clear Cache#).
With R# 2019.2.3 and using the new SDK .csproj format, which splits references between .NET references, NUGET packages, and project dependencies, there is a tendency for R# to still add a project reference under Assemblies, even when there is already a project reference under Dependencies. This results in the ambiguity error but can be hard to notice since the reference is in two separate places. Look for any project references that appear under Assemblies and remove them.
I was experiencing the same problem with references to C# classes in the AppCode folder.
I resolved this by upgrading my ReSharper to version 4.5 (from version 4.1).
It was a very simple upgrade, I just had to get the latest version from the JetBrains website (http://www.jetbrains.com/resharper/download/) and run it.
I did not have to uninstall the previous version (v4.1).
I did not have to re-enter my existing licence key.
All references are now recognised correctly and I can naviage to the classes as expected.
I encountered the same problem. The issue I had was caused by a custom build provider (from an open source library I'm using called PageMethods) and the fact that all my .aspx pages inherit from a BasePage class which lives in the App_Code folder.
I couldn't get any build of ReSharper to work with my project (4.1.933, 4.1.943 (latest) or 4.5). The fix in the latest ReSharper build fixes the "Ambiguous Reference" problem, but breaks the custom build provider.
The only way I could get both the build provider and base classes to work with ReSharper was to put the Base Classes into a separate class library.
The following are the logged Jira bugs that seem to relate to this issue:
False "Ambiguous reference" for
symbols from App_Code
Custom build provider may generate partial
class with second part residing in
app_code
I had same problem with ReSharper 5.1 and solved it by restarting Visual Studio 2010.
Using VS 2013 Premium & Resharper 8.1, and was getting this problem on an ASP.Net project.
The solution that worked for me:
Do a clean Solution.
Open references for the offending project
On each reference that refers to another project in the solution, set Copy Local = false.
Attempt a Rebuild Solution. You will likely get unresolved reference errors - that's normal.
Set each reference back to Copy Local = true (where appropriate)
In VS2022, simply cleaning the solution resolved the errors for me.

Resources