I have two VC++ projects inside a sln file in visual studio 2010. I want to use a_flag in the file of another project, is this possible what i am doing below ?
Project 1:
**sample_header.h**
#ifndef SAMPLE_HEADER_API
#define SAMPLE_HEADER_API __declspec(dllimport)
#endif
extern SAMPLE_HEADER_API int a_flg;
**file1.cpp**
#define SAMPLE_HEADER_API __declspec(dllexport)
#include "sample_header.h"
// Intialization of external
int a_flag = 15;
void m_func()
{
int i = 0;
}
Project 2:
**file2.h**
#include <stdio.h>
**file2.cpp**
#include "file1.h"
#include "sample_header.h"
// provided path of "sample_header.h" in additional include directory as well
void main()
{
if(a_flag > 0)
{
std::cout << "FLAG" ;
}
}
I set project1 as a DLL, project2 as an EXE project.
In linking, I am getting this error :
error LNK2001: `unresolved external symbol "__declspec(dllimport) int a_flg" (__imp_?a_flg##3HA)` in file2.cpp
I have read Microsoft page here about the DLL creation and linking but no idea how to resolve this external symbol error.
Thanks !
You need to set the project that creates your .dll to also generate the .lib file (an import library).
A quick description of the linkage should be something like this :
DLL Dependency Project -> dependecy.dll + dependency.lib
Main Project -> depends at runtime to depedency.dll , depends at link time to dependency.lib.
In other words, your .dll is just another binary that exposes some function signatures.
At runtime you can choose for either c linkage which involves querying the dll for the exposed functors/variables via name (the hard way, but useful when you don't have the .dll source code at hand) or use a more elegant way where you link the generated static library with your main.
When using the 1st approach, you will need to treat inside your code if you cannot find a certain .dll .
When using the 2nd approach, your binary will know that it depends on a certain .dll when you try to run it .
Here's an answer you will find very useful :
How do I build an import library (.lib) AND a DLL in Visual C++?
Related
I'm currently attempting to compile a VST3 plugin (or any C++ code, for that matter) for the first time, mainly just following Steinberg's own tutorial for all things except the actual sound processing.
Attempting to compile throws an "unresolved external symbol" error:
Error LNK2019 unresolved external symbol "public: __cdecl VSTGUI::VST3Editor::VST3Editor(class Steinberg::Vst::EditController *,char const *,char const *)" (??0VST3Editor#VSTGUI##QEAA#PEAVEditController#Vst#Steinberg##PEBD1#Z) referenced in function "public: virtual class Steinberg::IPlugView * __cdecl Itisdud::Split_TimesController::createView(char const *)" (?createView#Split_TimesController#Itisdud##UEAAPEAVIPlugView#Steinberg##PEBD#Z) Split_Times D:\programme\VST3Dev\Split_times\Split_Times\build\split_timescontroller.obj 1
The function that causes this, createView, is still the default it is when created by the Project Generator:
IPlugView* PLUGIN_API Split_TimesController::createView (FIDString name)
{
// Here the Host wants to open your editor (if you have one)
if (FIDStringsEqual (name, Vst::ViewType::kEditor))
{
// create your editor here and return a IPlugView ptr of it
auto* view = new VSTGUI::VST3Editor (this, "view", "split_timeseditor.uidesc");
return view;
}
return nullptr;
}
Copying the createView function from the again and adelay samples didn't work either.
As the Project generator only includes vstgui4/vstgui/plugin-bindings/vst3editor.h and not the vst3editor.cpp file, I tried including that as well (As I've read that not having the actual implementation there might be the cause of the issue), however that didn't fix the issue but made a lot of other errors happen upon compiling.
I also tried to follow this, including the cpp files noted there and changing the createView function to what is written there, however this also only led to there being a bit more than 300 errors upon compiling.
Copying the includes from the again sample didn't work either.
What would I need to include for this to work?
Those are the linker errors as you didn't instruct the linker where to find the required library files whose functions you are using.
Remember that compilation is a 2-step process that involves compilation and linking so it is best to separate them.
Lets assume you are using Visual Studio on Windows, and lets assume your VST SDK is installed on
C:\VST3SDK.
The first thing you should do is fire-up Visual Studio and select File->Open->CMake and go locate the CMake.txt file here
C:\VST3SDK\VST3_SDK.
After this file is loaded you will find on Visual Studio Solution Explorer a list of ready-made projects that come with the VST SDK loaded.
You will find that one of these projects is called Libraries and that is THE first action you have to do.
Now you have to build the correct library depending on whether you want to make 32-bits or 64-bits VSTs and you should set the configuration of the Libraries project accordingly.
You will build these libraries and if you hadn't changes any setting the libraries will be found at
C:\VST3SDK\VST3_SDK\out\build\x64-Debug\lib
or
C:\VST3SDK\VST3_SDK\out\build\x64-Release\lib
the necessary libraries being:
base.lib
pluginterfaces.lib
sdk.lib
sdk_common.lib
sdk_hosting.lib
vstgui.lib
vstgui_standalone.lib
vstgui.support.lib
vstgui_uidescription.lib
The above step ensures that you now have the necessary library files your VSTs will depend on.
Now assuming you have a VST sample project, lets say that you got from Git-hub and that it were written and setup correctly to run on Visual Studio, i.e. it came with a
myVST.vcxproj file.
Then you could paste the following pragmas on a prominent VST file such as the factory.cpp
#pragma comment(lib, "base.lib")
#pragma comment(lib, "pluginterfaces.lib")
#pragma comment(lib, "sdk.lib")
#pragma comment(lib, "sdk_common.lib")
#pragma comment(lib, "sdk_hosting.lib")
#pragma comment(lib, "vstgui.lib")
#pragma comment(lib, "vstgui_standalone.lib")
#pragma comment(lib, "vstgui_support.lib")
#pragma comment(lib,
"vstgui_uidescription.lib")
(Had to abbreviate due to confusing formatting requirements of this site but replace like "vstgui.lib" with a fully qualified path like
"C:/VST3SDK/VST3_SDK/out/build/x64-Debug/lib/vstgui.lib"
Now if your project properties
C/C++ _> General _> Additional Include Directories has correct entries that will tell the compiler the paths it will find ALL the #include files, then you will find that if you right click on any compilable file (c, cpp, rc ...) and select Compile then the file should successfully compile into an object file without any Compiler errors otherwise it is an indication that the compiler cannot find the required header
files.
But the problem you face are the linker problems, the linker can not find the required libraries of functions you have used in your project and the solution is just pasting the pragmas above.
I am trying a very simple implementation of a C++/CLI wrapper to allow legacy C++ code to reference .Net code, as described here. I am getting stuck just trying to get my basic C++/CLI unmanaged (native) objects linked, without even including any managed/IL/.Net code.
My question is, following along with this basic setup and what I describe below, am I right to be very confused about these errors? Are there some considerations that I'm missing? Maybe the answer is that this should work, so it's not clear what's wrong. That's still helpful. A similar working example would be great.
Unresolved Symbol Errors
Error LNK2019 unresolved external symbol "__declspec(dllimport)
public: __thiscall Wrapper::Test::Test(void)"
(__imp_??0Test#Wrapper##QAE#XZ) referenced in function _main NativeApp
Error LNK2019 unresolved external symbol "__declspec(dllimport)
public: __thiscall Wrapper::Test::~Test(void)"
(__imp_??1Test#Wrapper##QAE#XZ) referenced in function _main NativeApp
I've reviewed related questions on SO without any luck. I've got my dll header included in the client C++ project, my project reference to the C++/CLI wrapper dll, and my define statements for import/export. My very simple code is shown below. I am not using any MFC. I am using VS2017. DumpBin.exe /exports shows export symbols that seem to match what the linker error says are missing.
1 0 000010D0 ??0Test#Wrapper##QAE#XZ = ??0Test#Wrapper##QAE#XZ (public: __thiscall Wrapper::Test::Test(void))
2 1 000010E0 ??1Test#Wrapper##QAE#XZ = ??1Test#Wrapper##QAE#XZ (public: __thiscall Wrapper::Test::~Test(void))
3 2 000010C0 ??4Test#Wrapper##QAEAAV01#ABV01##Z = ??4Test#Wrapper##QAEAAV01#ABV01##Z (public: class Wrapper::Test & __thiscall Wrapper::Test::operator=(class Wrapper::Test const &))
Here's the basic code...
NativeApp.exe (project)
NativeApp.cpp (File)
#include "stdafx.h"
#include <iostream>
#include "Wrapper.h" //From additional includes directory
int main()
{
std::cout << "Program Started" << std::endl;
Wrapper::Test shell = Wrapper::Test::Test(); //Use dll
std::cin.get();
return 0;
}
Reference to Wrapper
Wrapper.dll (Project)
Wrapper.cpp (File)
#include "Wrapper.h"
#pragma unmanaged
namespace Wrapper {
Test::Test() {
}
Test::~Test() {
}
}
Wrapper.h (File)
#pragma once
#ifdef WRAPPER_EXPORTS
#define WRAPPER_API __declspec(dllexport)
#else
#define WRAPPER_API __declspec(dllimport)
#endif
#pragma unmanaged
namespace Wrapper {
class WRAPPER_API Test {
public:
Test();
~Test();
};
}
I was under the impression that the project reference took care of any additional dependency settings behind the scenes. Apparently, that is not the case. The .lib file needed to be added as an additional dependency, as is described here. However, as described by this Microsoft document, everything worked without additional dependencies when I was using non /clr dlls, so I'm not sure why the additional dependency was only required for my CLR reference. Clearly, I need to read up on this some more.
In any case, my C++ client project requirements are listed below. I was missing the second requirement. Also, here is an example project that helped me diagnose the problem.
1.) Add project reference
2.) Add the .lib file as an `Additional Dependency.
[Optional] Use Additional Library Directories
3.) #include .h file in code where appropriate
[Optional] Use additional include directories
EDIT: Why the additional dependency was required, and alternative option
As noted above, I was getting hung up on why the .lib additional dependency was required for the /clr dll but not for the non-clr dll. The answer is because a /clr project is configured by default to ignore import libraries. So when the project gets referenced by another C++ project, the project reference ignores import libraries. Changing this setting (Linker > General > Ignore Import Libraries) to "No" in the /clr dll project solves the issue so that the additional dependency is not required and the project reference works the same as the non-clr C++ dll.
I am using Octave within MSVC 2010. First I downloaded Octave latest version at this link. After installing, I tried to run this simple code:
#include <iostream>
#include<octave-3.6.4\octave\oct.h>
#include<octave-3.6.4\octave\config.h>
#include<octave-3.6.4\octave\octave.h>
using namespace std;
int main (void)
{
std::cout << "Hello Octave world!\n";
system("PAUSE");
return 0;
}
Note that I added these links to my project as well:
C:\Software\Octave-3.6.4\include\octave-3.6.4\octave--->Includ. Dir.,
C:\Software\Octave-3.6.4\include--->Includ. Dir.
C:\Software\Octave-3.6.4\lib--->Lib. Dir.
C:\Software\Octave-3.6.4\lib\octave\3.6.4--->Lib Dir.
I also added 1 and 2 to Additional Inc Dir!!
C:\Software\Octave-3.6.4\lib\octave\3.6.4--->Additional Lib. Dir in Linker.
First, I got this error that it cannot find math.h in Program Files while this file was in my Program Files (x86). So, I changed it to: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\math.h and it solved this error. However, now I get this error:
error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall octave_value::~octave_value(void)" (__imp_??1octave_value##QAE#XZ) referenced in function "public: void * __thiscall octave_value::`vector deleting destructor'(unsigned int)" (??_Eoctave_value##QAEPAXI#Z)
It is not sufficient to add the library path to the project.
You have to add the library name(s) (including .lib) to the "Additional Dependencies" in the Linker/Input tab.
Edit
To verify what library has been searched you can enable the Linker/General/Show Progress option. Then you can see in the Build Output what library has actually be used in symbol search.
Edit
Your example code doesn't show any instance of an array of octave_value instances. So it's a bit surprising that you need to link with any library with the code you've shown. But anyway you want to have these externals resolved.
If there is no other resource (manual, ...) you should detect where the octave_value class is implemented. This can be a static library or a DLL.
You can detect the DLL implementation with a dumpbin /exports on the DLLs. In that case you need the corresponding import libraries. The LIB should have the same base name as the DLL. Verify that you have added that dependency and how the linker searches this library for symbols.
The name of the symbols __imp_??1octave_value##QAE#XZ indicates that it should be in a DLL. But since you have a problem you might want to search LIBs too.
You can detect the LIB implementation with a dumpbin /symbols. In that case you have to add the LIB directly. Again verify it with the Build Output.
The dumpbin output will probably very verbose. You should use either findstr to limit the output or redirect the output to a file and search the symbols with an editor of your choice.
Search for ocatave_value. If you find a different decoration of the constructor and destructor you might have missed to set an option. A preprocessore directory could be used to define how the library is use. E.g. if you find octave_value::octave_value without the __imp_ prefix you have accidentily compiled for a DLL version altough the class is implemented in a static library. In that case, read the manual and ask at the octave mailing list forum or whatever.
I have one Visual Studio solution which consists of two win32 projects: 1) application (.exe) 2) functions wrapper (.dll).
The solution is in prototyping stage so all classes/functionality are implemented under (.exe) project - dirty but quick and easy for debugging/testing.
I've started to write a DLL wrapper to "play" with functionality in MSExcel/VBA and faced linking error
error LNK2019: unresolved external symbol "public: __thiscall Date::Date(int,int,int)" (??0Date##QAE#HHH#Z) referenced in function addNumbers
DLL header file:
#ifdef LIBRARYWRAP_EXPORTS
#define LIBRARYWRAP_API __declspec(dllexport)
#else
#define LIBRARYWRAP_API __declspec(dllimport)
#endif
LIBRARYWRAP_API int _stdcall addNumbers(int a, int b);
DLL source file:
#include "..\applicationProject\Date.h"
class Date;
LIBRARYWRAP_API int _stdcall addNumbers(int a, int b){
Date dummyDate(12,1,2014); // <- Linker error LNK2019.
return (a+b);
}
Class Date and constructor Date::Date(int,int,int) are defined in application project(.exe) within Date.h, Date.cpp.
What I've tried to do already:
for librarywrap project added new reference. Project -> Properties -> Common -> Add New Reference. Selected "applicationProject".
added additional include directories: $(SolutionDir)\applicationProject
Two questions:
First, Is that legal/achievable what I'm trying to do? DLL links to application project, whereas usually it should be other way round - application links to DLL. Hypothetically if i have two application projects (.exe) & (.exe) will it be possible to link one to another?
Second, If answer for first question is positive what should I add/change to make it work?
Thanks very much!
Nicholas
Technically, it is possible to make a DLL to call all needed functions from another modules (even from .exe ones - LoadLibrary can do this), but it would be a great pain: you will have to export all needed methods explicitly in the .EXE (just like you export DLL functions) and import them into your DLL. So the answer to the first question is yes, but if the DLL wants to use a lot of entry points from the EXE then probably it is not the best option.
I'd suggest a different approach: having a common code base for both .exe (application) and .dll projects. Then you will be able to test your code by running the application, and to use the functionality from other apps through the DLL (the DLL will contain all the necessary code itself).
I create two projects in VC++ Express 2010, one is DLLTest, the other is CODETest.
In DLLTest, declare and define a function func() as follows:
__declspec(dllexport) void func() {...};
Build DLLTest project successfully, DLLTest.dll and DLLTest.lib files created.
In CODETest, i want to use the exported function as follows:
#include "DLLTest.h"
int main()
{
...
func();
...
return 0;
}
Error occurs when build CODETest project--->"unresolved external symbol "void __cdecl letterList(void)" , but when i add DLLTest.lib into directory of CODETest project, build process successfully.
I dont know why? Thanks for help.
This seems all pretty unlikely, especially the part where "func" transformed into "letterList". Nevertheless, you have to tell the linker to also link the import library of the DLL so that it can resolve identifiers that are imported from that DLL. The easiest way to do that in MSVC is:
#include "DLLTest.h"
#pragma comment(lib, "dlltest.lib")
in CodeTest.cpp. The #pragma does the same thing as the linker's Additional Dependencies setting.