Importing functions from C static library in D? - static-libraries

I have already converted static lib to OMF format, but still have message like:
.dub\build\application-debug-windows-x86-dmd_2066-1C1E0ED068478598700706764846CD8E\ftdi.obj(ftdi)
Error 42: Symbol Undefined _FT_Open
In program I have import functions with method which I have already used. And it was worked for me with another libs.
pragma (lib, "ftd2xx_OMF.lib");
extern (C)
{
FT_STATUS FT_Open(FT_HANDLE, ulong*);
FT_STATUS FT_Close(FT_HANDLE);
//...
};
Library exists and really includes these functions. I've checked it through generating export/import lists by coffimplib.exe.
Any ideas?

Related

Attempt to access private member in dynamic_bitset

I am using Visual Studio 2017 to build LucenePlusPlus which in turn uses boost/dynamic_bitset.
The following code in LucenePlusPlus
const uint64_t* BitSet::getBits() {
return bitSet.empty() ? NULL : static_cast<const uint64_t*>(&bitSet.m_bits[0]);
}
generates the following fatal compiler error:
1>g:\luceneplusplus\src\core\util\bitset.cpp(20): error C2248: 'boost::dynamic_bitset<uint64_t,std::allocator<Block>>::m_bits': cannot access private member declared in class 'boost::dynamic_bitset<uint64_t,std::allocator<Block>>'
1> with
1> [
1> Block=uint64_t
1> ]
Suggestions?
I have traced the code for my boost 1_75_0 and I see it has a define to conditionally reserve access to friends:
#if defined(BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS)
#define BOOST_DYNAMIC_BITSET_PRIVATE public
#else
#define BOOST_DYNAMIC_BITSET_PRIVATE private
#endif
So it looks like you should be able to add -DBOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS to the compiler defines to fix this.
In fact, my LucenePlusPlus tree already contains it in
include/config_h/Config.h.in line 107:
#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
Previously ("rebuilt cmake buildsystem") this apparently
came from include/Config.h.cmake, where it was always present, unconditionally all the way since 2010:
What Can You Do?
Maybe you are not including the required headers that include the config? Also check any interfering precompiled header settings.
If you have boost/dynamic_bitset.hpp included BEFORE including LucenePlusPlus headers at any point you will run with the wrong config.
This is especially bad if you don't detect it because that would violate the ODR rule

What is the correct Java mapping of the shm_open function?

I'm trying to write some JNA code that accesses glibc, specifically functions defined in mmap.h.
I have tried to define it exactly as shown in man shm_open. The getuid() function call just before it works, but shm_open doesn't return.
I'm constrained to using JNA 4.4.0 and JNA Platform 3.4.0.
interface LibC extends Library {
LibC INSTANCE = Native.loadLibrary("c", LibC.class);
int shm_open(String name, int oFlag, int mode);
}
// ...
int fileDescriptor = LibC.INSTANCE.shm_open("/some_memory.123", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
// ...
I expect a file descriptor to be returned, but I get these exceptions:
When I load "libc.so.6": java.lang.UnsatisfiedLinkError: Error looking up function 'shm_open': /lib/x86_64-linux-gnu/libc.so.6: undefined symbol: shm_open
When I load "c": java.lang.UnsatisfiedLinkError: Error looking up function 'shm_open': /usr/lib/jvm/java-8-openjdk-amd64/bin/java: undefined symbol: shm_open
Well, I figured out the issue while writing the question.
While getuid() and friends are defined in libc, shm_open and friends are defined in librt. I really should have realized that because the manpage for shm_open explicitly states "Link with -lrt", indicating it residing in the "rt" lib.
In short: I need a new interface for LibRT alongside LibC, loaded with name rt.

undefined reference to '__gthrw___pthread_key_create(unsigned int*, void (*)(void*))

I'm using 64-bit gcc-4.8.2 to generate a 32-bit target, and my machine is 64-bit. I'm using c++11 concurrency features such as thread, mutex, conditiona_variables and etc.
The linker gave the above error message when trying to link the executable. libMyLib is also part of the project.
libMyLib.so: undefined reference to '__gthrw___pthread_key_create(unsigned int*, void (*)(void*))
nm libMyLib.so | grep pthread_key_create shows:
U _ZL28__gthrw___pthread_key_createPjPFvPvE
w __pthread_key_create##GLIBC_2.0
where is the symbol 'ghtrw___pthread_key_create' from? I tried adding '-lpthread(-pthread)' as compiler flag, but it does not help.
More information. nm libMyLib.so | grep pthread shows other symbols such as _ZL20__gthread_mutex_lockP15pthread_mutex_t is defined
where is the symbol 'ghtrw___pthread_key_create' from?
It is defined in GCC's "gthreads" abstraction layer for thread primitives, in the gthr-posix.h header.
#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
# ifndef __gthrw_pragma
# define __gthrw_pragma(pragma)
# endif
# define __gthrw2(name,name2,type) \
static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
__gthrw_pragma(weak type)
# define __gthrw_(name) __gthrw_ ## name
#else
# define __gthrw2(name,name2,type)
# define __gthrw_(name) name
#endif
/* Typically, __gthrw_foo is a weak reference to symbol foo. */
#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
...
#ifdef __GLIBC__
__gthrw2(__gthrw_(__pthread_key_create),
__pthread_key_create,
pthread_key_create)
After preprocessing that expands to:
static __typeof(pthread_key_create) __gthrw___pthread_key_create __attribute__ ((__weakref__("__pthread_key_create")));
It is supposed to be a weak reference to __pthread_key_create, so it should never have a definition, because it is just a reference to glibc's internal __pthread_key_create symbol.
So it looks like something has gone wrong with how you build you library. You should not have an undefined weak symbol.
I recently stumbled into this error, and not because of a missing -pthread.
The situation happened in a somewhat unusual setup: I was compiling a software written in C++14 under Centos7. Since C++14 requires a recent version of GCC, I relied on devtoolset 6 for it.
Given the specific setup, I opened a thread on the Centos mailing list, so I'm directly referencing the relevant thread. See https://lists.centos.org/pipermail/centos-devel/2018-May/016701.html and https://lists.centos.org/pipermail/centos-devel/2018-June/016727.html
In short, it might be caused by some bug in the preprocessor macros, either of glibc or libgcc. It can be fixed by placing #include <thread> in the beginning of the source code which gives problems once compiled. Yes, even if you don't use std::thread in it.
I don't claim this will work for everyone, but it might do the job in some particular situations.

How to link RtlIpv4StringToAddressExW function?

I am not able to link RtlIpv4StringToAddressExW(). This is a simplified version of my program.
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <Windows.h>
#include <cstdio>
#include <MSTcpIP.h>
HRESULT doMAin()
{
LONG error;
PSOCKADDR_IN sin4;
error = RtlIpv4StringToAddressExW(
L"127.0.0.1",
TRUE,
&sin4->sin_addr,
&sin4->sin_port);
return S_OK;
}
And the error I am getting is:
main.obj : error LNK2001: unresolved external symbol __imp__RtlIpv4StringToAddressExW#16
Does anyone know what could be wrong?
"An import library containing the RtlIpv4StringToAddressEx function is not included in the Microsoft Windows Software Development Kit (SDK) released for Windows Vista. The RtlIpv4StringToAddressEx function is included in the Ntdll.lib import library included in the Windows Driver Kit (WDK). An application could also use the GetModuleHandle and GetProcAddress functions to retrieve the function pointer from the Ntdll.dll and call this function."
from the docs.
If there was a lib to pragma comment, it would be Ntdll.lib. To repeat the docs, you can either grab the one from the DDK, or GetProcAddress the sucker.
GetProcAddressing would look like
typedef LONG (NTAPI *pfRtlIpv4StringToAddressEx)(PCWSTR,BOOLEAN,IN_ADDR *,PUSHORT);
pfRtlIpv4StringToAddressEx pRtlIpv4StringToAddressEx = (pfRtlIpv4StringToAddressEx)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlIpv4StringToAddressExW");
error = (*pRtlIpv4StringToAddressEx)(
L"127.0.0.1",
TRUE,
&sin4->sin_addr,
&sin4->sin_port);

Replacing DMD's kernel32.lib to include missing functions

I'm using dmd 2.054 and optlink 8.00.12 on Windows 7.
The following program:
pragma(lib, "kernel32.lib");
extern(Windows) {
uint LocaleNameToLCID(const(wchar)*, int);
}
void main() {
auto us = LocaleNameToLCID("en-US", 0);
}
Gives an error when compiling:
Error 42: Symbol Undefined _LocaleNameToLCID#8
But if I try to replace kernel32.lib, I get many errors:
implib /system kernel32.lib \Windows\system32\kernel32.dll
Error 42: Symbol Undefined _LocaleNameToLCID#8
c:\dmd\windows\bin\..\lib\phobos.lib(dmain2)
Error 42: Symbol Undefined _LocalFree#4
c:\dmd\windows\bin\..\lib\phobos.lib(dmain2)
(... snip ...)
Looking at the original lib and the implib created for LocalFree shows there are differences, but I'm not sure what that means (some special characters are missing from this output)
---------- IMPLIB
LocalFree
_LocalFreekernel32.dll LocalFree
_K32GetPerformanceInfo!_LocalFree!Z
_MoveFileExA!É_QueryPerformanceCounter!c_ReadConsoleOutputA!Ó
_LocalFreeZ
---------- DMD'S
LocalFree
_LocalFree#4KERNEL32.dll LocalFree
_LocalFree#4}
Any idea how I can use the new kernel32.lib in my programs to avoid missing symbols?
Nevermind..
I had also tried using coffimplib earlier without success, but now it works. No idea what I've done earlier.
So my solution has been to download the windows sdk and using coffimplib on the libraries I need.
Sorry for the spam. If someone could tell me why implib doesn't work I'll accept that answer.

Resources