I've a strange problem with linking a static member from a dll using Visual Studio Express 2010. On Linux platform
and MSYS/MinGW (GCC) this failure doesn't occurs.
I've a Math library using an export macro explicitly for this library module:
#ifdef WIN32
#ifdef MATH_LIBRARY_EXPORT
#define MATH_LIBRARY_API __declspec(dllexport)
#else
#define MATH_LIBRARY_API __declspec(dllimport)
#endif
#else
//define empty values for linux OS
#define MATH_LIBRARY_API
#endif
And this is a snipped of my Vector class i export with static members:
ifndef BINREV_VECTOR_H__
#define BINREV_VECTOR_H__
// include common header with dll import/export macro
#include <brMath/brCommons.h>
namespace binrev{
namespace brMath{
class MATH_LIBRARY_API brVector3f
{
public:
float m_fX, m_fY, m_fZ;
brVector3f(void);
brVector3f(float x, float y, float z);
...
public:
static const brVector3f ZERO;
static const brVector3f NEGATIVE_UNIT_Z;
...
};
And the cpp module:
// Ensure that the dll hader will be exported
#define MATH_LIBRARY_EXPORT
#include <brMath/brVector3f.h>
namespace binrev{
namespace brMath{
const brVector3f brVector3f::ZERO(0.0f, 0.0f, 0.0f);
const brVector3f brVector3f::NEGATIVE_UNIT_Z( 0.0f, 0.0f, -1.0f);
...
In my Graphics module (is also an dll with an different explicit export macro) using this Math dll i try to access one of those static members:
#include <brMath/brVector3f.h>
brMath::brVector3f brCamera::getDirection(void)
{
return m_orientation.rotate(brMath::brVector3f::NEGATIVE_UNIT_Z);
}
On the other platforms anything works well, but with MVSE 2010 i got
a linker failure:
1>------ Erstellen gestartet: Projekt: ZERO_CHECK, Konfiguration: Debug Win32 ------
2>------ Erstellen gestartet: Projekt: brGraphics, Konfiguration: Debug Win32 ------
2> brCamera.cpp
2>brCamera.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static class binrev::brMath::brVector3f const binrev::brMath::brVector3f::NEGATIVE_UNIT_Z" (?NEGATIVE_UNIT_Z#brVector3f#brMath#binrev##2V123#B)".
2>C:\binrev\repository\binrevengine\modules\brGraphics\trunk\bin\brGraphics.dll : fatal error LNK1120: 1 nicht aufgelöste externe Verweise.
========== Erstellen: 1 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
I'm not a friend of MVSE and this are my first tries to get our code runable with MVSE. While I've different solutions I've add the brMath.lib as additional dependency at the project settings. I've also set the path of the additional library directory to the location of my brMath.lib. This is the output of the linker command for review of my settings:
/OUT:"C:\binrev\repository\binrevengine\modules\brGraphics\trunk\bin\brGraphics.dll" /INCREMENTAL /NOLOGO
/LIBPATH:"C:\binrev\repository\binrevengine\modules\brMath\trunk\lib\Debug" /DLL "kernel32.lib" "user32.lib" "gdi32.lib"
"winspool.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "comdlg32.lib" "advapi32.lib" "brCore.lib" "brMath.lib"
"c:\binrev\development\vs2010\VC\lib\libboost_signals-vc100-mt-gd-1_47.lib" "c:\binrev \development\vs2010\VC\lib\libboost_system-vc100-mt-gd-1_47.lib"
/MANIFEST /ManifestFile:"brGraphics.dir\Debug\brGraphics.dll.intermediate.manifest" /ALLOWISOLATION
/MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\binrev\repository \binrevengine\modules\brGraphics\trunk\bin\brGraphics.pdb"
/SUBSYSTEM:CONSOLE /STACK:"10000000" /PGD:"C:\binrev\repository\binrevengine\modules\brGraphics\trunk\bin\brGraphics.pgd" /TLBID:1
/DYNAMICBASE /NXCOMPAT /IMPLIB:"C:/binrev/repository/binrevengine/modules/brGraphics /trunk/lib/Debug/brGraphics.lib" /MACHINE:X86 /ERRORREPORT:QUEUE
It seems too me that anything is linked correctly. When I remove the call of the const static dll member of brVector3f the build is successfull. I think there must be a problem with the const static member. But why in hell only with MVSE ?
I couldn't find any difference to this introducion: http://stackoverflow...c-data-in-a-dll
So it normally should be working ...
Now i running out of ideas what could be wrong.
I'm grateful for any help or hint.
"...When modifying a variable or function at file scope, the static keyword specifies that the variable or function has internal linkage (its name is not visible from outside the file in which it is declared)." from MSDN
Related
What is the bug in the following project?
main.cpp
#include "template_specialization_conflict_test.hpp"
int main()
{
std::cout << utils::my_template_function(0.555);
std::cout<<utils::my_template_function<double>(0.555);
return 0;
}
template_specialization_conflict_test.hpp
#ifndef UTILS__UTILS__UTILS__UTILS
#define UTILS__UTILS__UTILS__UTILS
#include <iostream>
namespace utils
{
// A generic function
template <class T>
T my_template_function(T parameter)
{
std::cout << "function template";
std::cout << parameter;
return parameter;
}
// Template Specialization
// A function specialized for double data type
template <>
double my_template_function<double>(double parameter)
{
std::cout << "function specialization on double";
std::cout << parameter;
return parameter;
}
}
#endif
template_specialization_conflict_test.cpp
#include "template_specialization_conflict_test.hpp"
namespace utils
{
//empty
}
Error
>------ Rebuild All started: Project: template_specialization_conflict_test, Configuration: x64-Debug ------
[1/1] Cleaning all built files...
Cleaning... 2 files.
[1/3] Building CXX object CMakeFiles\template_specialization_conflict_test.dir\main.cpp.obj
[2/3] Building CXX object CMakeFiles\template_specialization_conflict_test.dir\template_specialization_conflict_test.cpp.obj
[3/3] Linking CXX executable template_specialization_conflict_test.exe
FAILED: template_specialization_conflict_test.exe
cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\template_specialization_conflict_test.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\10.0.17763.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\10.0.17763.0\x64\mt.exe --manifests -- "C:\PROGRA~2\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\link.exe" /nologo CMakeFiles\template_specialization_conflict_test.dir\template_specialization_conflict_test.cpp.obj CMakeFiles\template_specialization_conflict_test.dir\main.cpp.obj /out:template_specialization_conflict_test.exe /implib:template_specialization_conflict_test.lib /pdb:template_specialization_conflict_test.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
LINK Pass 1: command "C:\PROGRA~2\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\link.exe /nologo CMakeFiles\template_specialization_conflict_test.dir\template_specialization_conflict_test.cpp.obj CMakeFiles\template_specialization_conflict_test.dir\main.cpp.obj /out:template_specialization_conflict_test.exe /implib:template_specialization_conflict_test.lib /pdb:template_specialization_conflict_test.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\template_specialization_conflict_test.dir/intermediate.manifest CMakeFiles\template_specialization_conflict_test.dir/manifest.res" failed (exit code 1169) with the following output:
C:\Users\pc\source\repos\template_specialization_conflict_test\out\build\x64-Debug\main.cpp.obj : error LNK2005: "double __cdecl utils::my_template_function<double>(double)" (??$my_template_function#N#utils##YANN#Z) already defined in template_specialization_conflict_test.cpp.obj
C:\Users\pc\source\repos\template_specialization_conflict_test\out\build\x64-Debug\template_specialization_conflict_test.exe : fatal error LNK1169: one or more multiply defined symbols found
ninja: build stopped: subcommand failed.
Rebuild All failed.
How can I fix this?
How can I fix this?
You could solve this by adding/using the keyword inline for the specialization so the specialization would look like:
//note the keyword inline in the below specialization
template <> inline
double my_template_function<double>(double parameter)
{
std::cout << "function specialization on double";
std::cout << parameter;
return parameter;
}
This works as can be seen here.
Second way to solve this would be to move your specialization into the source file instead of the header. So your template_specialization_conflict_test.cpp would look like:
template_specialization_conflict_test.cpp
#include "template_specialization_conflict_test.hpp"
namespace utils
{
// Template Specialization
// A function specialized for double data type
template <>
double my_template_function<double>(double parameter)
{
std::cout << "function specialization on double";
std::cout << parameter;
return parameter;
}
}
The program works as can be seen here and here(with gcc and clang).
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 started a new QT Creator project based on the SUBDIRS template and then recreated two subprojects; one DLL project and one exectuable that needs to use classes from the DLL.
I added the DLL library as an "Internal" library (and not as "external" because I figured it was in my build tree) to the executable. I have a class declared in my DLL and added the "export" specifier.
I am having trouble using it in the EXE project. It complains about unresolved external symbol. I tried adding "using MyClass;" at the top of main.cpp, but this didn't help. What do I need in place before I can use a class from my DLL project in the executable? Thanks!
Here is some code to add detail.
/////////// Main.cpp from Executable project ////////////////////////////////////////////////
#define USEDLL 1;
#include <QCoreApplication>
#include "../Library/myclass.h"
#include <QDebug>
#include <iostream>
//__declspec(dllimport) MyClass;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
__declspec(dllimport) MyClass g;
QString test;
test = MyClass::TheString();
return a.exec();
}
//////////////// Class Header in DLL ////////////////////////////////
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QString>
#ifdef ISDLL
#define DLL __declspec(dllexport)
#endif
#ifdef USEDLL
#define DLL __declspec(dllimport)
#endif
class DLL MyClass
{
public:
MyClass();
static QString TheString();
};
#endif // MYCLASS_H
////////////////// Class cpp from DLL project /////////////////////////
#define ISDLL 1;
#include "myclass.h"
MyClass::MyClass()
{
}
QString MyClass::TheString()
{
return "test";
}
//////////////////////////// Compiler output ////////////////////////////
11:09:59: Running steps for project Top...
11:09:59: Configuration unchanged, skipping qmake step.
11:09:59: Starting: "C:\Qt\Tools\QtCreator\bin\jom.exe"
cd Library\ && ( if not exist Makefile C:\Qt\5.1.1\msvc2010\bin\qmake.exe D:\Projects\Top\Library\Library.pro -spec win32-msvc2010 CONFIG+=debug CONFIG+=declarative_debug CONFIG+=qml_debug -o Makefile ) && C:\Qt\Tools\QtCreator\bin\jom.exe -f Makefile
C:\Qt\Tools\QtCreator\bin\jom.exe -f Makefile.Debug
cd App\ && ( if not exist Makefile C:\Qt\5.1.1\msvc2010\bin\qmake.exe D:\Projects\Top\App\App.pro -spec win32-msvc2010 CONFIG+=debug CONFIG+=declarative_debug CONFIG+=qml_debug -o Makefile ) && C:\Qt\Tools\QtCreator\bin\jom.exe -f Makefile
C:\Qt\Tools\QtCreator\bin\jom.exe -f Makefile.Debug
cl -c -nologo -Zm200 -Zc:wchar_t -Zi -MDd -GR -W3 -w34100 -w34189 -EHsc -DUNICODE -DWIN32 -DQT_QML_DEBUG -DQT_DECLARATIVE_DEBUG -DQT_CORE_LIB -I"C:\Qt\5.1.1\msvc2010\include" -I"C:\Qt\5.1.1\msvc2010\include\QtCore" -I"debug" -I"." -I"C:\Qt\5.1.1\msvc2010\mkspecs\win32-msvc2010" -Fodebug\ #C:\Users\philip\AppData\Local\Temp\main.obj.4512.0.jom
main.cpp
echo 1 /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 24 /* RT_MANIFEST */ "debug\\App.exe.embed.manifest">debug\App.exe_manifest.rc
if not exist debug\App.exe if exist debug\App.exe.embed.manifest del debug\App.exe.embed.manifest
if exist debug\App.exe.embed.manifest copy /Y debug\App.exe.embed.manifest debug\App.exe_manifest.bak
link /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\App.exe.embed.manifest /OUT:debug\App.exe #C:\Users\philip\AppData\Local\Temp\App.exe.4512.687.jom
main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class QString __cdecl MyClass::TheString(void)" (__imp_?TheString#MyClass##SA?AVQString##XZ) referenced in function _main
debug\App.exe : fatal error LNK1120: 1 unresolved externals
jom: D:\Projects\build-Top-Desktop_Qt_5_1_1_MSVC2010_32bit-Debug\App\Makefile.Debug [debug\App.exe] Error 1120
jom: D:\Projects\build-Top-Desktop_Qt_5_1_1_MSVC2010_32bit-Debug\App\Makefile [debug] Error 2
jom: D:\Projects\build-Top-Desktop_Qt_5_1_1_MSVC2010_32bit-Debug\Makefile [sub-App-make_first-ordered] Error 2
11:10:00: The process "C:\Qt\Tools\QtCreator\bin\jom.exe" exited with code 2.
Error while building/deploying project Top (kit: Desktop Qt 5.1.1 MSVC2010 32bit)
When executing step 'Make'
11:10:00: Elapsed time: 00:01.
Did you put it to LIBS in pro-file? Check make files for linker flags.
This question is closely related to a question that was previously asked here.
In order for the Visual Studio 2010 C++ debugger to resolve in-class-initialized const variables, a global definition for the variable must be supplied.
e.g.
Here is the class definition:
class B{
public:
static const int m_b=100;
};
Here is the global scope definition of the member:
const int B::m_b;
Without the global definition the code works but the debugger cannot see m_b within B's methods.
However, this leads to another problem. In non-trivial header file inclusion arrangements (full code given below), Visual Studio produces this link error:
error LNK2005: "public: static int const B::m_b" (?m_b#B##2HB) already defined in a.obj
1>a.exe : fatal error LNK1169: one or more multiply defined symbols found
However GCC compiles, links, and runs the code successfully.
Here is the code in question:
file a.cpp:
#include <iostream>
#include "a.h"
const int B::m_b;
int main()
{
B b;
std::cout << b.m_b;
return 0;
}
file a.h:
#pragma once
#include "b.h"
file b.cpp:
#include "b.h"
file b.h:
#pragma once
class B {
public:
static const int m_b = 100;
};
Here are the linker options (default VS10 console program):
/OUT:"a.exe"
/NOLOGO "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib"
/MANIFEST
/ManifestFile:"Debug\a.exe.intermediate.manifest"
/ALLOWISOLATION
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/DEBUG
/PDB:"Debug\a.pdb"
/PGD:"Debug\a.pgd"
/TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE
Here are the compiler options (default VS10 console program):
/ZI /nologo /W3 /WX- /Od /Oy- /D "_MBCS" /Gm /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t
/Zc:forScope /Fp"Debug\sndbx.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd
/analyze- /errorReport:queue
Again, this builds, links, and runs successfully with GCC ( g++ a.cpp b.cpp ). The code I've supplied is complete so it can be copied, pasted, and run.
You shouldn't put non-template definitions of data in header files, because you will get multiple definition errors at link time. Whether the variable is a member variable or a static member variable or a const static member variable doesn't change this at all.
Put the definition in exactly one compilation unit, just like you would for any other singleton.
This actually looks like a Visual C++ bug. It would have helped considerably if you had shown the complete error message, namely
b.obj : error LNK2005: "public: static int const B::m_b" (?m_b#B##2HB) already defined in a.obj
a.exe : fatal error LNK1169: one or more multiply defined symbols found
The symbol would not be defined anywhere in b.obj if the compiler were working right.
Furthermore, attempting to use __declspec(selectany) tells us that the compiler knows this is not a definition:
r:\16404173\b.h(3) : error C2496: 'B::m_b' : 'selectany' can only be applied to
data items with external linkage
Finally, Visual C++ clearly is defining the symbol (incorrectly):
R:\16404173>dumpbin /symbols b.obj
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file b.obj
File Type: COFF OBJECT
COFF SYMBOL TABLE
000 00AB9D1B ABS notype Static | #comp.id
001 00000000 SECT1 notype Static | .drectve
Section length 2F, #relocs 0, #linenums 0, checksum 0
003 00000000 SECT2 notype Static | .debug$S
Section length 64, #relocs 0, #linenums 0, checksum 0
005 00000000 SECT3 notype Static | .rdata
Section length 4, #relocs 0, #linenums 0, checksum B4446054, selection 2 (pick any)
007 00000000 SECT3 notype External | ?m_b#B##2HB (public: static int const B::m_b)
Furthermore, we see that it is marked as selectany already. But in the compilation unit with the actual definition:
Section length 4, #relocs 0, #linenums 0, checksum B4446054
229 00000000 SECTB9 notype External | ?m_b#B##2HB (public: static int const B::m_b)
The (pick any) annotation is gone. Which is proper, this is an authoritative definition of the variable.
It's wrong for the variable to appear in b.obj at all. The compiler makes the simple case (initialization inside header file) work by using the selectany annotation, but this hackish workaround falls apart when a real definition is provided.
Finally, adding __declspec(selectany) on the real definition, in a.cpp, works around the link error. But I'm afraid the symbol will still be optimized away by the linker and not available during debugging. You can temporarily use the /OPT:NOREF to avoid this (but it will bloat your executable, so turn that option off again before shipping).
According to what clang will accept, the static const variable initialisation must happen in the definition rather than the declaration.
Therefore in your header you want this:
class B{
public:
static const int m_b;
};
And then the definition in your cpp should be like this:
const int B::m_b = 100;
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