I have been searching for an answer to this but no luck as yet.
Using Qt5.5 32bit, VS2013 on Win8 64bit
My .pro file contains this:
INCLUDEPATH += "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include"
LIBS += -L"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib" -ladvapi32
I have checked both folders and WinUser.h is in the Include and User32.lib is present in the Lib.
I have the following two functions in my code:
void suppressAnimations()
{
ANIMATIONINFO m_original_settings;
m_original_settings.cbSize = sizeof(m_original_settings);
if (::SystemParametersInfo(SPI_GETANIMATION, sizeof(m_original_settings), &m_original_settings, 0)) {
ANIMATIONINFO no_animation = { sizeof(no_animation), 0 };
::SystemParametersInfo(SPI_SETANIMATION, sizeof(no_animation), &no_animation, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
}
}
AND
int BackgroundTaskManager::changeMonitorState(bool turnOn)
{
int lparam = 2;
if(turnOn) {
lparam = -1;
BackgroundTaskManager::MonitorIsSleeping = false;
} else {
lparam = 2;
BackgroundTaskManager::MonitorIsSleeping = true;
}
return SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)lparam);
}
I use this exact same code with Qt 5.3.2 32bit VS2010 on Windows 7 64bit and it compiles with no problems. In my current configuration, I get linking errors on the ::SystemParametersInfo and the SendMessage parts of the functions and a bunch of warnings on the headers.
Warnings
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include\sal_supp.h:57: warning: C4005: '__useHeader' : macro redefinition
Linking Errors
main.obj:-1: error: LNK2019: unresolved external symbol __imp__SystemParametersInfoW#16 referenced in function "void __cdecl suppressAnimations(void)" (?suppressAnimations##YAXXZ)
backgroundtaskmanager.obj:-1: error: LNK2019: unresolved external symbol __imp__SendMessageW#16 referenced in function "private: int __thiscall BackgroundTaskManager::changeMonitorState(bool)" (?changeMonitorState#BackgroundTaskManager##AAEH_N#Z)
Another bit of information, I tried this also using Qt5.5 32bit VS2013 on Win7 64bit and also received the errors as above. Yet another bit of information, in Qt Creator, I can press F2 over either of the symbols above and it takes me to the correct header.
Could someone point me in the correct direction?
I knew it was something simple:
LIBS += -L"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib" -ladvapi32 -luser32
I did not link the user32.lib.
Related
Usually we load a dll on windows and call it's functions which is marked as __declspec(dllexport), but can I call a function which is implemented in the loaded program from a dll?
Firstly speaking this can be done on Linux, check the question I asked earlier.
I wrote a test program to test this:
CMakeList.txt (sorry I'm new to Windows programming and don't know how to use visual studio):
cmake_minimum_required(VERSION 3.16)
project(untitled4)
set(CMAKE_CXX_STANDARD 17)
add_library(lib1 SHARED lib1.cpp)
add_executable(untitled4 main.cpp)
main.cpp
#include "iostream"
#include "windows.h"
extern "C" {
// this is the function I want to get called from dll
__declspec(dllexport)
float get_e() {
return 2.71;
}
}
int main() {
auto *handler = LoadLibrary("lib1.dll");
if (!handler) {
std::cerr << ERROR_DELAY_LOAD_FAILED << std::endl;
exit(1);
}
auto p = (float (*)()) GetProcAddress(handler, "get_pi");
std::cout << p() << std::endl;
}
lib1.cpp:
#include "iostream"
extern "C" {
// implemented in main.cpp
__declspec(dllimport)
float get_e();
__declspec(dllexport)
float get_pi() {
std::cout << get_e() << std::endl; // comment this line will compile, just like the normal case
return 3.14;
}
}
The compile will fail when building lib1:
NMAKE : fatal error U1077: '"C:\Program Files\JetBrains\CLion 2020.1.1\bin\cmake\win\bin\cmake.exe"' : return code '0xffffffff'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.27.29110\bin\HostX86\x64\nmake.exe"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.27.29110\bin\HostX86\x64\nmake.exe"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.27.29110\bin\HostX86\x64\nmake.exe"' : return code '0x2'
LINK Pass 1: command "C:\PROGRA~2\MICROS~2\2019\BUILDT~1\VC\Tools\MSVC\1427~1.291\bin\Hostx86\x64\link.exe /nologo #CMakeFiles\lib1.dir\objects1.rsp /out:lib1.dll /implib:lib1.lib /pdb:C:\Users\derwe\CLionProjects\untitled\cmake-build-debug\lib1.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\lib1.dir/intermediate.manifest CMakeFiles\lib1.dir/manifest.res" failed (exit code 1120) with the following output:
Creating library lib1.lib and object lib1.exp
lib1.cpp.obj : error LNK2019: unresolved external symbol __imp_get_e referenced in function get_pi
lib1.dll : fatal error LNK1120: 1 unresolved externals
Stop.
So can I do this on windows? That is to call a function in main from a dll?
P.S. Ideas of adding a registry function in dll and pass get_e through it is thanks but cannot be considered in my real case.
Since you are using late binding for your .dll, you might do the same thing for function defined in the executable. Just call GetProcAddress in the same way, using this process handle (as it is already in the address space). Here is some (pseudo) code:
auto proc = GetModuleHandle(nullptr);
auto get_e = reinterpret_cast<float (*) ()>(GetProcAddress(proc, "get_e"));
I know this question has been asked a lot of times already but I'm sorry, I just can't figure out what is wrong with what I've been doing.
What I want is to read a DICOM image (by pixel because I have to perform operations on it) and display it on a Qt GUI.
I have Windows 8 and Visual Studio 2013. I downloaded Qt opensource and also VS's plugin for it. I built Qt using cmake-gui. Then, I followed what was said on a discussion here in stackoverflow entitled "How to use DCMTK in Qt". I downloaded DCMTK 3.6.0, configured and generated it using cmake-gui, built its ALL_BUILD and INSTALL projects in VS. So far, everything is successful. Then I tried creating a simple program that will read a DICOM image and display it.
I created a new Qt Application and named it MainWindow. Here is my mainwindow.cpp:
#include "mainwindow.h"
#include <dcmtk\config\osconfig.h>
#include <dcmtk\ofstd\ofcond.h>
#include <dcmtk\ofstd\ofstring.h>
#include <dcmtk\dcmdata\dctk.h>
#include <dcmtk\dcmdata\dcfilefo.h>
#include <dcmtk\dcmdata\dcitem.h>
#include <dcmtk\dcmdata\dcdeftag.h>
#include <dcmtk\dcmdata\dctagkey.h>
void MainWindow::tryDCMTK() {
DcmFileFormat fileformat;
OFCondition status = fileformat.loadFile("C:/Users/Kriselle/Documents/000004.dcm");
if (status.good())
{
OFString patientsName;
if (fileformat.getDataset()->findAndGetOFString(DCM_PatientName, patientsName).good())
{
printf("Patient's Name: %s",patientsName);
}
else
printf("Error: cannot access Patient's Name!");
}
else
printf("Error: cannot read DICOM file (%s)", status.text());
}
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
ui.setupUi(this);
}
MainWindow::~MainWindow() {}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets/QMainWindow>
#include "ui_mainwindow.h"
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindowClass ui;
void tryDCMTK();
};
#endif // MAINWINDOW_H
MainWindow.pro
# ----------------------------------------------------
# This file is generated by the Qt Visual Studio Add-in.
# ------------------------------------------------------
TEMPLATE = app
TARGET = MainWindow
DESTDIR = ../Win32/Debug
QT += core widgets gui
CONFIG += debug console
DEFINES += WIN64 QT_DLL QT_WIDGETS_LIB _REENTRANT
INCLUDEPATH += ./GeneratedFiles \
. \
./GeneratedFiles/Debug \
"C:/Program Files (x86)/DCMTK/include"
DEPENDPATH += .
MOC_DIR += ./GeneratedFiles/debug
OBJECTS_DIR += debug
UI_DIR += ./GeneratedFiles
RCC_DIR += ./GeneratedFiles
HEADERS += ../../../../../../../DICOMSDL/include/dicom.h \
./dicomcfg.h \
./mainwindow.h
SOURCES += ./main.cpp \
./mainwindow.cpp
FORMS += ./mainwindow.ui
RESOURCES += mainwindow.qrc
QMAKE_CFLAGS_RELEASE -= -MD
QMAKE_CFLAGS_RELEASE = -MT
QMAKE_CFLAGS_DEBUG -= -MDd
QMAKE_CFLAGS_DEBUG = -MTd
QMAKE_CXXFLAGS_RELEASE -= -MD
QMAKE_CXXFLAGS_RELEASE += -MT
QMAKE_CXXFLAGS_DEBUG -= -MDd
QMAKE_CXXFLAGS_DEBUG += -MTd
#a example: LIBS += -L"../../../test_dcmtk/DCMTK/lib" \
LIBS += -L"C:/Program Files (x86)/DCMTK/lib" \
-lconfig \
-lofstd \
-ldcmdata \
-loflog \
-lws2_32 \
-lnetapi32 \
-lwsock32 \
-ladvapi32
When I tried to run it, the following 7 LNK2019 errors occurred:
1>mainwindow.obj : error LNK2019: unresolved external symbol "public: __cdecl OFString::OFString(void)" (??0OFString##QEAA#XZ) referenced in function "private: void __cdecl MainWindow::tryDCMTK(void)" (?tryDCMTK#MainWindow##AEAAXXZ)
1>mainwindow.obj : error LNK2019: unresolved external symbol "public: __cdecl OFString::~OFString(void)" (??1OFString##QEAA#XZ) referenced in function "private: void __cdecl MainWindow::tryDCMTK(void)" (?tryDCMTK#MainWindow##AEAAXXZ)
1>mainwindow.obj : error LNK2019: unresolved external symbol "public: class OFCondition __cdecl DcmItem::findAndGetOFString(class DcmTagKey const &,class OFString &,unsigned long,bool)" (?findAndGetOFString#DcmItem##QEAA?AVOFCondition##AEBVDcmTagKey##AEAVOFString##K_N#Z) referenced in function "private: void __cdecl MainWindow::tryDCMTK(void)" (?tryDCMTK#MainWindow##AEAAXXZ)
1>mainwindow.obj : error LNK2019: unresolved external symbol "public: __cdecl DcmFileFormat::DcmFileFormat(void)" (??0DcmFileFormat##QEAA#XZ) referenced in function "private: void __cdecl MainWindow::tryDCMTK(void)" (?tryDCMTK#MainWindow##AEAAXXZ)
1>mainwindow.obj : error LNK2019: unresolved external symbol "public: virtual __cdecl DcmFileFormat::~DcmFileFormat(void)" (??1DcmFileFormat##UEAA#XZ) referenced in function "private: void __cdecl MainWindow::tryDCMTK(void)" (?tryDCMTK#MainWindow##AEAAXXZ)
1>mainwindow.obj : error LNK2019: unresolved external symbol "public: class DcmDataset * __cdecl DcmFileFormat::getDataset(void)" (?getDataset#DcmFileFormat##QEAAPEAVDcmDataset##XZ) referenced in function "private: void __cdecl MainWindow::tryDCMTK(void)" (?tryDCMTK#MainWindow##AEAAXXZ)
1>mainwindow.obj : error LNK2019: unresolved external symbol "public: virtual class OFCondition __cdecl DcmFileFormat::loadFile(char const *,enum E_TransferSyntax,enum E_GrpLenEncoding,unsigned long,enum E_FileReadMode)" (?loadFile#DcmFileFormat##UEAA?AVOFCondition##PEBDW4E_TransferSyntax##W4E_GrpLenEncoding##KW4E_FileReadMode###Z) referenced in function "private: void __cdecl MainWindow::tryDCMTK(void)" (?tryDCMTK#MainWindow##AEAAXXZ)
1>C:\Users\Kriselle\documents\visual studio 2013\Projects\MainWindow\x64\Debug\\MainWindow.exe : fatal error LNK1120: 7 unresolved externals
I have looked into other discussions:
*Link 1** said that the libraries must be linked in properties->linker->additional library dependencies. I already did that. Screenshots of my additional library dependencies and environment variables are available in the zip file attached below.
*Link 2** has a different error output. (I was already past that).
*Link 3** said "look for linker flags/settings inside a project configuration dialog" but I don't know what's wrong with my linker settings. I even listed the libraries inside the lib directory in my Additional Dependencies. (A screenshot of my Additional Dependencies is also included in the zip file below.)
I have also done what was suggested at *Link 4**.
Furthermore, I believe I didn't commit the same mistake as displayed in *Link 5** because I have no parameters for my function.
The images are here: https://db.tt/CmpJndan
The links of online discussions I have looked into are here: https://db.tt/AOsewqUg
As much as I would like to make it easier for you to see the images and navigate to the links, I am very sorry, I can only post a maximum of two links due to my lack of reputation.
Please help me. Thank you very much for your time!
EDIT: I changed the order of my libraries according to their dependencies and added NetAPI32.lib and WSock32.lib to my libraries thanks to the link Hans gave in the comments. But I still get the same errors.
For a proof-of-concept, I want to link some trivial Haskell code into my Visual C++ application (using Visual Studio 2013). Building with GHC 7.8.3 32-bit works, but building with GHC 7.8.4 64-bit does not (notice the slight discrepancy in GHC version too).
There are 3 files: Grep.hs and StartEnd.c are built with GHC to form a DLL. main.cpp is built with Visual Studio 2013 and attempts to link in the DLL library.
I am building the DLL from this:
> ghc -shared -O -optc-O -o Grep.dll StartEnd.c Grep.hs
And from within Visual Studio, I simply link against Grep.dll.a and include C:\Program Files\MinGHC-7.8.4\ghc-7.8.4\lib\include, but linking fails with
1>main.obj : error LNK2001: unresolved external symbol _HsEnd
1>main.obj : error LNK2001: unresolved external symbol _freegrep
1>main.obj : error LNK2001: unresolved external symbol _grep
1>main.obj : error LNK2001: unresolved external symbol _HsStart
1>C:\Code\Grep\dist\Win32\Release\Grep.exe : fatal error LNK1120: 4 unresolved externals
The exact same process works when I build with 32-bit, but not 64-bit. What could I be doing wrong? (I am building a 64-bit app when attempting to link the 64-bit library.)
Source files:
Grep.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Grep where
import Foreign
import Foreign.C.String
import Data.List (isInfixOf)
filterlines f = unlines . filter f . lines
grep :: CString -> CString -> IO CString
grep i s = do
ii <- peekCString i
ss <- peekCString s
newCString $ (filterlines (isInfixOf ii)) ss
freegrep :: CString -> IO ()
freegrep s = free s
foreign export ccall grep :: CString -> CString -> IO CString
foreign export ccall freegrep :: CString -> IO ()
StartEnd.c
#include <Rts.h>
void HsStart()
{
int argc = 1;
char* argv[] = {"ghcDll", NULL}; // argv must end with NULL
// Initialize Haskell runtime
char** args = argv;
hs_init(&argc, &args);
}
void HsEnd()
{
hs_exit();
}
main.cpp
#include <HsFFI.h>
#include <Grep_stub.h>
#include <iostream>
extern "C" {
void HsStart();
void HsEnd();
}
int main(int argc, char* argv[])
{
HsStart();
HsPtr str;
str = grep("test", "This is a test\nwith many lines\nand it failed\nand the test passed");
if (str)
{
std::cout << (char*) str;
freegrep(str);
}
HsEnd();
return 0;
}
Thanks to the comments, I added the actual error output to the post. This caused me to notice that Visual Studio's confusing configuration management interface had bit me once again. It was still trying to build the Win32 version even though my configuration setting said x64. Long story short, it's working!
I'm following the instructions, which tell me to download msgpack 0.5.4 for C & C++.
On Windows, download source package from here and extract it. Open msgpack_vc8.vcproj or msgpack_vc2008 file and build it using batch build. It builds libraries in lib/ folder and header files in include/ folder.
You can build using command line as follows:
vcbuild msgpack_vc2008.vcproj
dir lib % DLL files are here
dir include % header files are here
vcbuild msgpack_vc2008.vcproj has been replaced by MSBuild msgpack_vc8.vcxproj. I used Visual studio 2012 to convert the project to have the correct .vcxproj for this. Batch build in Visual studio and running MSBuild gives the same result, so I will speak for both of them from this point on.
After the project is converted, I noticed the project was set to output to .lib, rather than .dll, so I altered that setting to match my needs. When compiling there was one small error:
...\microsoft visual studio 11.0\vc\include\stdint.h(8): error C2371: 'int8_t' : redefinition; different basic types
...msgpack-0.5.4\src\msgpack\sysdep.h(23) : see declaration of 'int8_t'
So I changed the line
typedef __int8 int8_t;
to
typedef signed __int8 int8_t;
which solves that minor issue. But then we arrive at where I'm at now. This linker error:
objectc.obj : error LNK2019: unresolved external symbol __imp__ntohl#4 referenced in function _msgpack_pack_array
unpack.obj : error LNK2001: unresolved external symbol __imp__ntohl#4
objectc.obj : error LNK2019: unresolved external symbol __imp__ntohs#4 referenced in function _msgpack_pack_array
unpack.obj : error LNK2001: unresolved external symbol __imp__ntohs#4
...\msgpack-0.5.4\Debug\MessagePack.dll : fatal error LNK1120: 2 unresolved externals
I've searched for parts of this error:
In sysdep.h:
#define _msgpack_be16(x) ntohs(x)
#define _msgpack_be32(x) ntohl(x)
In object.c:
case MSGPACK_OBJECT_ARRAY:
{
int ret = msgpack_pack_array(pk, d.via.array.size);
if(ret < 0) { return ret; }
msgpack_object* o = d.via.array.ptr;
msgpack_object* const oend = d.via.array.ptr + d.via.array.size;
for(; o != oend; ++o) {
ret = msgpack_pack_object(pk, *o);
if(ret < 0) { return ret; }
}
In unpack.c:
static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_object* o)
{
o->type = MSGPACK_OBJECT_ARRAY;
o->via.array.size = 0;
o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object));
if(o->via.array.ptr == NULL) { return -1; }
return 0;
}
And that's about all I know. If there's another way of how to obtain the .dll, that would be helpful too. Thank you in advance. :)
You need to link the ws2_32.lib library since ntohl is a winsocket API function.
That should fix the problem!
Hey Folks i am trying to compile this C++ program:
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <Windows.h>
#include "Validate.h"
JNIEXPORT jstring JNICALL Java_Validate_takeInfo(JNIEnv *env, jobject obj,
jstring domain, jstring id, jstring idca, jstring password)
{
const char *nt_domain;
const char *nt_id;
const char *nt_idca;
const char *nt_password;
nt_domain = env->GetStringUTFChars(domain, NULL);
nt_id = env->GetStringUTFChars(id, NULL);
nt_idca= env->GetStringUTFChars(idca, NULL);
nt_password = env->GetStringUTFChars(password, NULL);
HANDLE hToken = 0;
char *otherString;
bool aut;
aut = LogonUser(nt_id, nt_domain, nt_password, LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT, &hToken );
if(aut)
{
otherString = "true";
}
else
{
otherString = "false";
}
jstring newString = env->NewStringUTF((const char*)otherString);
return newString;
}
int main()
{
return 0;
}
Using this command:
cl -I"c:\Program files\Java\jdk1.5.0_07\include"
-I"C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include"
-I"c:\program files\java\jdk1.5.0_07\include\win32"
-LD D:\JNI\%filename%.cpp -D:\JNI\Fe%filename%.dll -link
-LIBPATH:"C:\Program Files\Microsoft Visual Studio 8\VC\lib"
-LIBPATH:"C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Lib"
However i always get the following error:
Validate.obj : error LNK2019: unresolved external symbol __imp__LogonUserA#24
referenced in function _Java_Validate_takeInfo#24
Validate.dll : fatal error LNK1120: 1 unresolved externals
I have probably tried a thousand different ways to compile playing with the LIBPATH switch.
-link -LIBPATH:"C:\Program Files\Microsoft Visual Studio 8\VC\lib";"C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Lib"
and many others.
[Update] if i switch around the lib paths and put "\PlatformSDK\lib" before the "\VC\lib" switch i get this error:
LINK : fatal error LNK1104: cannot open file 'uuid.lib'
becuase it now cannot recognise the other libpath. Any idea? [/Update]
How do i declare multiple libpaths? is there something else causing this?
As always, thanks guys
MSDN says that LogonUser is in Advapi32.lib. It looks like the problem is that you're not including Advapi32.lib. LIBPATH affects where the linker searches for libraries, not what libraries the linker searches for, and nowhere are you telling the linker to search for Advapi32.dll.
On Visual C++ 2008, you should be able to do include Advapi32.lib by going under Project, Properties, Configuration Properties, Linker, Additional Dependencies. I'm not sure about other versions.)
From the command line, you should be able to just list Advapi32.lib as an additional file to be linked. Try this:
cl -I"c:\Program files\Java\jdk1.5.0_07\include"
-I"C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include"
-I"c:\program files\java\jdk1.5.0_07\include\win32"
-LD D:\JNI\%filename%.cpp -D:\JNI\Fe%filename%.dll -link
-LIBPATH:"C:\Program Files\Microsoft Visual Studio 8\VC\lib"
-LIBPATH:"C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Lib"
Advapi32.lib