visual studio 2012 can't resolve static fields in a dll lib - dll

I'm compiling openexr2.0.0 using visual studio 2012 x64 dll, I got this error:
ImfLut.obj : error LNK2001: unresolved external symbol "private: static union half::uif const * const half::_toFloat" (?_toFloat#half##0QBTuif#1#B)
ImfRgbaYca.obj : error LNK2001: unresolved external symbol "private: static unsigned short const * const half::_eLut" (?_eLut#half##0QBGB)
And I looked up in the half.lib using dumpbin /exports:
Another look up using dumpbin /exports on half.dll:
The two symbols are there. And interestingly, when I remove half.lib from dependency, VS complain convert is also unresolved. This shows that it could find convert but not _toFloat and _eLut. The differences are: _toFloat and _eLut are both static fields, convert is a static method.
class half
{
...
public:
union uif
{
unsigned int i;
float f;
};
private:
HALF_EXPORT static short convert (int i);
HALF_EXPORT static const uif _toFloat[1 << 16];
HALF_EXPORT static const unsigned short _eLut[1 << 9];
...
};
My system is windows 8 x64. Does anyone know how to fix this problem?

You're trying to link against __declspec(dllexport)-ed symbols.
This means you need to make sure you're __declspec(dllimport)-ing those symbols in your project file.
Specifically to half - there's a #define you can add: OPENEXR_DLL that is being checked for appearance in halfExport.h and will do that for you.

Step 14 in the following link solved the problem for me:
https://groups.google.com/forum/#!topic/openvdb-forum/-jFJQ2N4BGc
In your project, add OPENEXR_DLL to "Preprocessor Definitions" in "project properties->C/C++->Preprocessor"

Related

Linking an unknown dll

I've got this dll (called unknown.dll) from which i only know what Ghidra told me. I'm using LoadLibraryW to load it, but (in x86) it throws me the error 126. However, in 64x it gives me the error 193, so i don't think that the problem is that my program can't find my dll...
Here is my code :
#include <iostream>
#include <Windows.h>
typedef int(__cdecl* FunctionIWant)();
int main()
{
HMODULE hmod = LoadLibraryW(L"C:\\unknown.dll");
if (hmod != NULL)
{
...
}
else
std::cout << GetLastError();
return 0;
}
What am I doing wrong ?
126 is ERROR_MOD_NOT_FOUND. Either your DLL can't be found, or more likely one if it's dependencies can't be found.
193 is ERROR_BAD_EXE_FORMAT. This is because you can't mix 32 and 64 bit DLLs.
The fact that you get ERROR_BAD_EXE_FORMAT when you run under 64 bit tells you that your DLL is found. Therefore we can conclude that its dependencies are not present.
Consult the documentation to discover what dependencies are required.

Why doesn't Clion recognise WxPuts?

The wxPuts method used in this tutorial (http://zetcode.com/gui/wxwidgets/helperclasses/) doesn't work. Was it changed and the class is no longer available?
I tried searching online for some documentation about wxPuts and wxPrintf, but can't find anything relevant in the helper files in the wxWidg site.
#include <wx/textfile.h>
int main(int argc, char **argv)
{
wxTextFile file(wxT("test.c"));
file.Open();
wxPrintf(wxT("Number of lines: %d\n"), file.GetLineCount());
wxPrintf(wxT("First line: %s\n"), file.GetFirstLine().c_str());
wxPrintf(wxT("Last line: %s\n"), file.GetLastLine().c_str());
wxPuts(wxT("-------------------------------------"));
wxString s;
for ( s = file.GetFirstLine(); !file.Eof();
s = file.GetNextLine() )
{
wxPuts(s);
}
file.Close();
}
wxWidgets provides wrappers for all standard CRT functions working with strings in order to allow calling them with wxString or wchar_t (wide) strings. These wrappers are not documented because it doesn't make much sense to re-document the standard functions, but basically for any foo(const char* s) in the standard library, you have wxFoo(const wxString& s) declared in wx/crt.h header. You have to include this header to get these declarations, however.
Also note that most of wxWidgets functionality can't be used before the library is initialized.
TL;DR: you're missing #include <wx/crt.h>.

Exporting TASKLET in kernel module?

I got two kernel modules which both exports some symbols using EXPORT_SYMBOL().
One of them exports basic function (sv1<-sv2) and it works but I got problem with the other one (sv1->sv2).
What I want is to export TASKLET. I read somewhere that is possibile and there is no proscription of doing this. Module nr 1 (called sv1) consists of BH Function and declaration of tasklet:
struct tasklet_struct sv_takslet;
EXPORT_SYMBOL(sv_takslet);
void sv_tasklet_function( unsigned long data )
{
printk( "%s\n", (char *)data );
return;
}
static int __init sv_publisher_init(void)
{
...
tasklet_init(&sv_takslet, &sv_tasklet_function,&sv_tasklet_data);
...
}
In second module there is global reference and task_schedule() function used at initialization of the module nr 2 (called sv2):
extern struct tasklet_struct sv_takslet;
...
tasklet_schedule(&sv_takslet);
The problem is when I got:
tasklet_schedule(&sv_takslet);
in my code I do not see my two modules on list (modprobe -l), but when I comment this line on sv2- they magically appear.
What could be a cause of that behavior? Is this initialization is correct?
EDIT
The cause of this problem is that module sv2 is loading before sv1 and has no knowledge about the tasklet (line: extern struct tasklet_struct sv_takslet). When I change destination that sv2 exports TASKLET to sv1 the problem is gone.
But now I am facing with that both modules have to export symbols to each other. I have no idea how to solve this problem...
Both *.c files are in the same directory and my Makefile has following line:
obj-m += sv_publisher.o zsv_core.o
Does anybody have some tips how to go about it?

DLL import failure in using WinDivert

I am going to design a program using WinDivert to manipulate the network traffic.
The language I use is C++ and the program is designed under Visual Studio 2008.
Firstly I create a project in visual C++ CLR (Windows Forms Application) so I can implement the UI simply.
For importing the WinDirvert Library, I have done the following setting in project properties:
Configuaration Properties: General
Common Language Runtime support: Common Language Runtime Support(/ctr)
Configuaration Properties: Linker
Additional Dependencies: link of WinDivert.lib
Module Definition File: link of windivert.def
Within the project I have created, I also added the windivert.h in the header files.
Also, windivert.h is included in the main entry point of my project (ProjectG.cpp):
#include "stdafx.h"
#include "Form1.h"
#pragma managed(push, off)
#include "windivert.h"
#pragma managed(pop)
using namespace ProjectG;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
HANDLE handle;
unsigned char packet[8192];
UINT packet_len;
WINDIVERT_ADDRESS addr;
handle = WinDivertOpen("udp", WINDIVERT_LAYER_NETWORK, 0,
WINDIVERT_FLAG_DROP);
if (handle == INVALID_HANDLE_VALUE)
{
Application::Exit();
}
while (TRUE)
{
// Read a matching packet.
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
{
MessageBox::Show("Fail");
continue;
}
}
return 0;
}
Finally, I put the {WinDivert.dll, windivert.h, WinDivert.lib, WinDivert32.sys} under the project directory.
However, the following error is shown:
fatal error LNK1306: DLL entry point "int __clrcall main(cli::array<class
System::String ^ >^)" (?main##$$HYMHP$01AP$AAVString#System###Z) cannot be managed;
compile to native ProjectG.obj ProjectG
Additional: (a warning)
warning LNK4070: /OUT:WinDivert.dll directive in .EXP differs from output filename
'C:\Users\David\Desktop\css\ProjectG\Debug\ProjectG.exe'; ignoring directive
ProjectG.exp ProjectG
Question:
How can I resolve this situation?
a) your main source is .cpp, so you can delete [STAThreadAttribute] and change
int main(array<System::String ^> ^args) to int _tmain(int argc, _TCHAR* argv[])
b) exclude windivert.def from linker Module Definition File, this only when you are creating a DLL
c) the DLL/SYS files would need to be copied to the Debug and Release folders

Create C++/CLI Wrapper for native C++ code

I currently need to write a C++/CLI wrapper for a native C++ library (TetGen) for later use in a C# project. I have read quite a few articles on how to do this but am at a loss with my linker errors. A chap called "Sam Agten" tried to accomplish this too, as he states in his Blog which led me to a series on C++ Interop (Part 1, Part 2, Part 3, Part 4, Part 5), where Part 3 is supposed to explain how to do what I accomplish.
Because Sam wanted to integrate TetGen with Unity he at last had to resort to C-Style-Wrappers. Now, if I'm not entirely mistaken, I have tried using C-Style-Wrappers on a previous, related project.
Because my wrapped TetGen must run on a Windows Server (2008 I think) my first question is:
Will a C++/CLI-Wrapper work in a Server-Environment?
I started writing a very simple wrapper according to aforementioned Part 3, which failed miserably. Anyway I tried to create a simple wrapper library along the line of thought, which I want to share with you. I began by creating a C#-project which ultimatly should use my wrapped library and added first a new project from the "Win32"-subsection of C++-projects "SimpleAdd".
//SimpleAdd.h
class _declspec(dllexport) SimpleAdd
{
public:
SimpleAdd();
~SimpleAdd();
int Add(int a,int b);
};
//SimpleAdd.cpp
#include "SimpleAdd.h"
int SimpleAdd::Add(int a, int b)
{
return a+b;
}
In the project settings I made sure, that it compiled to a static library (*.lib) and no CLR-Support was used. From the preprocessor definition I assume the lib is to target x86 systems: "WIN32". Everything is left pretty much on standard values. If I right-click => build it will successfully build a lib called "SimpleAdd.lib".
One thing I was pointed to through other posts: If I open the lib in DependencyWalker, I get an error saying: "No DOS or PE signature found. This file is not a valid 32-bit or 64-bit Windows module" which is kind of frustrating. What do I have to to to make DependencyWalker stop showing this error, since I think this 32/64-problem might hint to a solution.
Anyway, I have my lib, now I want to wrap it up. So I created a new project in my solution called "AddWrapper", using the CLR-ClassLibrary-template of the C++-branch.
// AddWrapper.h
#pragma once
#include "..\SimpleAdd\SimpleAdd.h"
using namespace System;
namespace AddWrapper {
public ref class ManagedSimpleAdd
{
private:
SimpleAdd *sa;
public:
ManagedSimpleAdd();
~ManagedSimpleAdd();
int Add(int a, int b);
};
}
//AddWrapper.cpp
#include "AddWrapper.h"
using namespace AddWrapper;
ManagedSimpleAdd::ManagedSimpleAdd() : sa(new SimpleAdd())
{
}
ManagedSimpleAdd::~ManagedSimpleAdd(){delete sa;}
int ManagedSimpleAdd::Add(int a, int b)
{
return sa->Add(a,b);
}
As both C++-projects are in seperate folders on the same hierarchical level, I specified the relative path to the headerfile. In the project settings I now have the configuration standard .dll and the /clr-switch. In my VC++ folders I added the path to the Debug-directory of my whole soultion, because this is where the referenced lib is compiled to. In my linker-settings under "additional dependencies" I added the name: "SimpleAdd.lib".
When I want to build my wrapper however, there is a problem, or rather 5 of them:
Fehler 3 error LNK2028: Nicht aufgel÷stes Token (0A00000B) ""public: __thiscall SimpleAdd::SimpleAdd(void)" (??0SimpleAdd##$$FQAE#XZ)", auf das in Funktion ""public: __clrcall AddWrapper::ManagedSimpleAdd::ManagedSimpleAdd(void)" (??0ManagedSimpleAdd#AddWrapper##$$FQ$AAM#XZ)" verwiesen wird. %path%\AddWrapper\AddWrapper.obj AddWrapper
Fehler 4 error LNK2028: Nicht aufgel÷stes Token (0A00000C) ""public: __thiscall SimpleAdd::~SimpleAdd(void)" (??1SimpleAdd##$$FQAE#XZ)", auf das in Funktion ""public: void * __thiscall SimpleAdd::scalar deleting destructor'(unsigned int)" (??_GSimpleAdd##$$FQAEPAXI#Z)" verwiesen wird. %path%\AddWrapper\AddWrapper.obj AddWrapper
Fehler 5 error LNK2019: Verweis auf nicht aufgel÷stes externes Symbol ""public: __thiscall SimpleAdd::SimpleAdd(void)" (??0SimpleAdd##$$FQAE#XZ)" in Funktion ""public: __clrcall AddWrapper::ManagedSimpleAdd::ManagedSimpleAdd(void)" (??0ManagedSimpleAdd#AddWrapper##$$FQ$AAM#XZ)". %path%\AddWrapper\AddWrapper.obj AddWrapper
Fehler 6 error LNK2019: Verweis auf nicht aufgel÷stes externes Symbol ""public: __thiscall SimpleAdd::~SimpleAdd(void)" (??1SimpleAdd##$$FQAE#XZ)" in Funktion ""public: void * __thiscall SimpleAdd::scalar deleting destructor'(unsigned int)" (??_GSimpleAdd##$$FQAEPAXI#Z)". %path%\AddWrapper\AddWrapper.obj AddWrapper
Fehler 7 error LNK1120: 4 nicht aufgel÷ste Externe %path%\Debug\AddWrapper.dll 1 1 AddWrapper
Now, what could be the cause of these errors? Is it the platform-befuddeledness of the lib? Did I miss to specify something else?
What do I have to to to make DependencyWalker stop showing this error
Do not compile to a lib file! It's not an executable and it's not a dynamic link library so it has not PE signature. You can build a static library and link it inside your C++/CLI assembly (if you wish so) or you can simply put all that code inside your C++/CLI assembly. Up to you.
what could be the cause of these errors?
You directly included header file, let me highlight your code:
class _declspec(dllexport) SimpleAdd
As you can see you're actually compiling with _declspec(dllexport), you're not telling the compiler to import such class from a library but that you're exporting it (and linker will complain because you declared that class but there is not any implementation). When you include a class it has to be declared with _declspec(dllimport).
class _declspec(dllimport) SimpleAdd
Usually this trick is done with preprocessor macros. Let me make a simplified example. In your SimpleAdd.h file you can declare:
#if defined(SIMPLEADD_LIB)
#define SIMPLEADD_EXPORTED _declspec(dllexport)
#else
#define SIMPLEADD_EXPORTED _declspec(dllimport)
#endif
Then change your code to
class SIMPLEADD_EXPORTED SimpleAdd
In your SimpleAdd project you define a macro (from Project settings) named SIMPLEADD_LIB. This will cause your library to be built with dllexport (because from library you export that class) but in your C++/CLI wrapper to be declared as dllimport (right because SIMPLEADD_LIB isn't declared and there you're importing that class).