C++, WinRT, VS2017, Windows10, Bluetooth LE
I have a stand-alone C++/WinRT VS2017 console app that was used for testing code to control a Bluetooth LE device. That console app works and I am now in the process of moving that code into an existing C++ MFC VS2017 app which also works.
In the existing MFC app I first installed the NuGet cppwinrt package that I used in the test console app (no problems)
I then put the various WinRt header files that were in the console app's pch.h into the MFC's stdafx.h file
#pragma comment(lib, "windowsapp")
#include <condition_variable>
#include "winrt\Windows.Foundation.h"
#include "winrt\Windows.Storage.Streams.h"
#include "winrt\Windows.Devices.Bluetooth.h"
#include "winrt\Windows.Devices.Bluetooth.Advertisement.h"
#include "winrt\Windows.Devices.Bluetooth.GenericAttributeProfile.h"
So far, so good. The MFC app still compiles without problems. However, I then put the "using namespace" entries, that were at the top of the console app's .cpp file, into the MFC's ...View.cpp and that is when I get the compile problems
using namespace winrt;
using namespace Windows::Foundation;
using namespace winrt::Windows::Foundation;
using namespace Windows::Storage::Streams;
using namespace Windows::Devices::Bluetooth;
using namespace Windows::Foundation::Collections;
using namespace Windows::Devices::Bluetooth::Advertisement;
using namespace Windows::Devices::Bluetooth::GenericAttributeProfile;
The compile error I get is:
Error C2872 'IUnknown': ambiguous symbol MyMFCApp c:\program files
(x86)\microsoft visual
studio\2017\professional\vc\tools\msvc\14.16.27023\atlmfc\include\atlcom.h 3456
I see that IUnknown seems to be fairly universal throughout Windows APIs. How should I go about clearing up this error?
#AlanBirtles answer seems to have solved the problem. In the console app I could not compile without these using namespace entries so I just assumed that I would also need them in the MFC app. As I mentioned in my comment above, all of the namespaces compiled in the MFC app except for the two Foundation namespaces.
//using namespace Windows::Foundation; // errors IUnknown
//using namespace winrt::Windows::Foundation; // errors IUnknown
I left the rest and commented these two out and then added the code to create the BluetoothLEAdvertisementWatcher, attach a callback for the watcher.Received() and let it find my device. It ran fine. I have not yet tried with the rest of the namespaces commented out but I will.
I did try #IInspectable suggestion for using the #include <unknwn.h> before all of the WinRT namespaces. I put that in at the top and then uncommented one of the two Foundation namespaces but still got the ambiguous IUnknown error.
So the answer seems to be (for my situation anyway) that the namespaces were not necessary...at least the two Foundation namespaces.
Thanks for the help. It is really appreciated.
I'm trying to reproduce an issue, so I have created an empty MFC C++ application using the VS2019 wizard and a separate native Unit Test project.
Before adding the Unit Test project, the MFC application compiled and launched successfully.
The MFC application still compiles successfully, but the Unit Test project will not compile. I'm getting two errors:
E0035 #error directive: "include 'pch.h' before including this file for PCH"
C1189 #error: "include 'pch.h' before including this file for PCH"
However, the only file in the Unit Test project (UnitTest1.cpp) already includes pch.h at the top of the file:
#include "pch.h"
#include "CppUnitTest.h"
#include "../MFCApplication1/MFCApplication1.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest1
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(TestMethod1)
{
CMFCApplication1App app;
bool result = app.InitInstance();
Assert::IsTrue(result);
}
};
}
It seems to be telling me to do something that is already done.
What's going on here?
Try to include stdafx.h and remove pch.h, it resolves the issue
I had the same issue. I found that I could not include the MFC DLL project's default header file directly. In your example this would be #include "../MFCApplication1/MFCApplication1.h"
I eventually found this example MFC DLL project code: https://github.com/Microsoft/VCSamples/tree/master/VC2010Samples/MFC/advanced from a list of examples here.
Notice that in the example that the default header/implementation files created by the MFC DLL project creation wizard (in this example, DLLScreenCap.h) don't export or provide any additional functionality. An existing MFC DLL project that I work with did the same.
So I added a class to the MFC DLL project to be tested and exported a simple function from it, and tested this exported function from my unit test project after linking to the project under test.
Exported class and function look like this:
#pragma once
class __declspec(dllexport) MFCLibraryExports
{
public:
// tests returning 17 to test unit test library against an mfc project
int SampleExport();
};
In your example I know that you are trying to test an instanced app and my answer doesn't help with that, but I was able to confirm that I can test at least a function exported from an MFC DLL project using the MS Unit Test framework. I'm not sure if you are expected to be able to get access to the application from a unit test as in your example; I am not able to include that header directly.
Here says that you may put DEBUG_NEW in place of new in your MFC app. When I do so the compiler says that DEBUG_NEW is not defined. It is VS 2017. _DEBUG is defined. What can be wrong?
[edit]
I should note first I placed it as a global define for the whole project. There were thousands of errors (it is a big project). Then I changed just one occurrence. One that was in my code. And it is not working. is included but is not directly
You need to be more specific. Where are you placing it?
In a newly generated MFC app, they usually put these lines in the .cpp files after the includes (see last 3 lines):
// LangInfo.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "LangInfo.h"
#include "LangInfoDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
I am upgrading my preexisting CAD/CAM project (quite big one > 10MByte of code) and have to add some special measuring equipment. The problem is I have more than one supplier of the measuring system (although is already decided which one to use) and I want to configure them (using #define in case vendor is changed in future) with code to use only selected device type. So I have something like:
#define use_vendor1
//#define use_vendor2
//#define use_vendor3
and some of the vendors APIs require their own DLLs so I need for example:
Project/Add to project/vendor1.lib
Project/Remove from project/unused_vendor.lib
if use_vendor1 is used ... That will be uncomfortable to add/remove each type reconfiguration of exe is required. I was wondering if there exist a way similar to this:
#ifdef use_vendor1
#pragme link "vendor1.lib"
#endif
That one does not work of coarse because DLL *.lib is not compiled code as *.obj ...
Having all the libs in the project is an option but that would require shipping exe with all the DLL's which I would rather avoid.
Another option would be dynamic DLL link but I rather avoid it as that is more coding for me in it...
I am bound to old BDS2006 Turbo C++ Explorer IDE and compiler.
Also is it possible to statically link DLL in relative path to EXE ?
You are looking for #pragma comment:
#ifdef use_vendor1
#pragma comment(lib, "vendor1.lib")
#endif
I inherited a substantial amount of code, including a visual studio project that is supposed to (as best as I can tell) build a .lib file. Visual studio says "... Generating Code... Creating Library... Creating browse information file...", and at the end, it says the build succeeded. In the release/debug folder, it has a bunch of .obj files, but it doesn't have a .lib file. What could I be missing?
Thanks!
Open the Project Properties (right-click the project in Solution Explorer, select 'Properties'). Under 'Librarian', check 'Output File' - that's where the output should go.
If this looks right, try dir /s *.lib in a suitable subdirectory for your project, to see if you can locate the output library by date and time. If you still can't find it, try a clean rebuild (right click project, select 'Rebuild').
For DLLs, a .Lib file is not created if the DLL exports nothing for external usage. I don't think this applies for static lib builds but I would make sure you are exporting something public from your library project source code.
.lib will not get generated if you miss to add prefix __declspec(dllexport) for methods.
My static library contains nothing but two template classes, so I didn't have a .cpp file. This caused Visual Studio 2015 to not output a .lib file. To solve this, I made a file huh.cpp which includes all of the headers.
I had the same problem, even though I was already using the __declspec(dllexport) function.
Your ProjectName.cpp file needs to #include "ProjectName.h". If you don't include the header file then the functions don't get exported. The DLL builds fine, no errors or warnings (at least in VS2017 15.8), but you don't get a LIB file.
Include the header and boom - LIB file is generated. A rookie mistake I'm sure, but everyone has to start learning somewhere.
If the Methods you want to export are in a class, you have to __declspec(dllexport) on the class. Otherwise no .lib will be created.
In my case (Visual Studio 2019), when #include "pch.h" was not the very first include statement in cpp, lib file was not created.
I just ran across this problem as well.
It was due to using an invalid macro in the output directory definition. In my case, it was
when it should have been
I had to blank out the full path in the second screen shot. I had an incorrect macro. I was using MsBuildProjectDir when I should have been using MsBuildProjectDirectory. The read-only text box will show the full path (eg: C:\Development\blah\blah\blah\) when the output directory is valid. If the output directory is not valid, you'll get something like the first screenshot.
In the DLL project, put __declspec(dllexport) beginnings of methods defined in .h and .cpp files.
After all, compile your dll again, so .lib file will be generated and ready for linking.
put Class Foo
{
public:
__declspec(dllexport) int GetFoo() const;
I was exporting a class from the dll but had declared the class inline in .h file. The .cpp file was there but empty. This setup was causing the .lib file to be not generated.
I moved the implementation of functions to .cpp file and now lib file is generated.
This is in VS2019.
Had the same issue here with VS2019. In my case I had built a few times with no symbols defined (i.e. cpp files were empty).
After I added symbol definitions into the cpp files I began to notice this issue (no lib file was being generated).
A simple clean via 'Rebuild all' fixed it. Perhaps if you build whilst there are no symbols defined, something gets cached somewhere that you have an empty product DLL, and you need to clean the solution to reset that cached state.
My issue was that in the projects Properties>C/C++>CommandLine, I had specfied the switch incorrectly.
That is instead of writting /D_HASHING_BUILD_DLL I had written /D_Hashing_BUILD_DLL.
Side note:
This is how I build my DLL/Lib files in Visual studio : (and my Hashing.h looks like this: )
#ifndef HASHING_H
#define HASHING_H
/* If we are we on Windows, we want a single define for it.*/
#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
#define _WIN32
#endif /* _WIN32 */
#if defined(_WIN32) && defined(_HASHING_BUILD_DLL)
/* We are building Hashing as a Win32 DLL */
#define HASHING_API __declspec(dllexport)
#elif defined(_WIN32) && defined(HASHING_DLL)
/* We are calling Hashing as a Win32 DLL */
#define HASHING_API __declspec(dllimport)
#elif defined(__GNUC__) && defined(_HASHING_BUILD_DLL)
/* We are building Hashing as a shared / dynamic library */
#define HASHING_API __attribute__((visibility("default")))
#else
/* We are building or calling HASHING as a static library */
#define HASHING_API
#endif
//your inlcudes
class HASHING_API MyClass
{
//...
};
#endif // !HASHING_H
and in the path I stated earlier, I just use the switch I defined here and there you go, the DLL is built just fine!
I'm not so familiar with C++ and I had the same issue. I thought I would share what worked for me. It appears that the import/export must come after the class statement, according to the following page.
https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4091?view=msvc-160
// Warning C4091
// No error but didn't produce a .lib file
__declspec(dllimport) class X {};
// __declspec attribute after the class or struct keyword
// applies to user defined type worked
class __declspec(dllimport) X3 {};
Sometimes when you break you head in a new project why .lib is not created - it can be some "past games" issue.
I was creating a new .dll but before I decided to use #define with __declspec(dllexport)/__declspec(dllimport) I tried to play with .def
After removing .def file it probably left some misconfiguration in the project file and it wasn't creating .lib file...
Till I decided to just remove the project completly and recreate - and walla, works perfectly!