xcode 4.6 symbol visibility - xcode

I have slight problem or misunderstanding with hiding symbols in xcode 4.6. I have searched everywhere in the web and cant find any posts having the same issue.
Currently I have created a framework project with a simple header file containing so:
class Test
{
public:
Test(){}
Test(){}
};
int a(int n) {return n;}
__attribute__((visibility("hidden"))) int b(int n) {return n;}
__attribute__((visibility("default"))) int c(int n) {return n;}
class X
{
public:
virtual ~X();
};
class __attribute__((visibility("hidden"))) Y
{
public:
virtual ~Y();
};
class __attribute__((visibility("default"))) Z
{
public:
virtual ~Z();
};
X::~X() { }
Y::~Y() { }
Z::~Z() { }
In the project settings i have made sure that "Symbols hidden by default" is switched to YES and therefore only the functions int c and the class z will be exported or visible to other projects.
I build the framework with no errors or warnings and then copy/add it to a cocoa application for testing.
I am able to include the header file but I am still able to access all classes and functions.
I hope someone can explain why or where i am going wrong or have encountered this problem before?
regards

Your problem is, you are declaring everything in the header file. That means even if the symbols are not exported, when you import the header file into another file, these symbols are re-created in the project where you imported the header and thus they are of course available within this project.
I'm trying to explain this to you by a simpler sample. Assume you have two files, MyLib.h and MyLib.c.
MyLib.h:
int add(int a, int b);
MyLib.c:
int add(int a, int b) { return a + b };
If you now give add a hidden visibility and compile everything to a library (MyLib), the library will have no symbol for add (as it is hidden). As a result, if you include MyLib.h into another file, make a call to the add function there and finally link this file against MyLib, you will get a linker error, since the linker will complain that it cannot find an implementation for add (it only has a declaration from the H file).
However, if you pack the function into the header itself, so MyLib.h is:
int add(int a, int b) { return a + b };
and you give add a hidden visibility, the library will also have no symbol for add, but when you include the header into another file, this header will create a symbol for add in exactly the file that imported it and thus of course you will not get a linker error and be able to call add.
Importing a H file just means copying the whole content of the H file to the location where the import instruction has been found. Now think about it: If you copy the whole content of the H file in your question to the top of the file where you are including it, of course all symbols declared there are visible and usable in the current project. Why wouldn't they be visible or useable? They are not in the library, yes, but they are in the header and thus do get compiled when your other project is compiled.
Symbols that are supposed to not be visible outside your current project ("hidden" symbols) should never appear in any public header file of your framework. Why would you announce the existence of symbols in a header files that cannot be used anyway? Actually, in most cases not exposing the symbols in the header file is already enough to prevent people from using them. The reason for not exporting them either is only that if a symbol exists, it can be used, even if it is not exposed by any header file (therefor you just need to write your own header file or declaring it as external symbol directly in your code). So making symbols hidden is just a safeguard to make sure that it cannot be used under any circumstances.

Related

cygwin warning: COMDAT symbol does not match section name

I am using g++ (5.4.0) on cygwin, to compile and link some cpp files. Compilation goes through fine, but during linking I get many errors like:
lib.a: warning: COMDAT symbol '.pdata$_ZnwmPv' does not match section name '.pdata'
lib.a: warning: COMDAT symbol '.xdata$_ZnwmPv' does not match section name '.xdata'
I am not able to figure out what this message means, nor how to fix the problem. I tried a google search, and got this link: https://sourceware.org/bugzilla/show_bug.cgi?id=15041
It seems to indicate that the problem is fixed and checked in, way back in 2013.
So does my error message mean that this fix is not available in the gcc of cygwin? Or is there something else that I need to do to fix/bypass this problem?
Also, is there any way I can get more details on what exactly is the mismatch? That may indicate what I need to fix in my code.
Some more details : The warning occurs only in cygwin, and not in ubuntu, so I have also added the cygwin tag to this question and also mentioned cygwin in the question. And it happens only when I add the following code to my classes. If the addObject2 method is deleted, and the private member _obj2Array is made public and its code is moved to the application, then the warning goes away.
myObject1.h:
class myObject1: public myParent {
... // constructors, etc
vector<myObject2*> _obj2Array;
public:
void addObject2(myObject2* obj2);
}
myObject1.cpp:
void myObject1::addObject2(myObject2* obj2) {
_obj2Array.push_back(obj2);
}

Specify a "back-up" load path with Load-Time Dynamic Linking?

When using 'Load-Time Dynamic Linking'(using an import library .lib in compilation that loads a dll when the module is loaded) in a Win32 application, is it possible to affect the search order?
The goal is to have a library loaded using the normal search order, with a back-up path if one is not found on the normal path.
Example: foo.lib is linked in the project. At load time:
If foo.dll is present in the System path or any of the other paths mentioned in Dynamic-Link Library Search Order then it will be loaded.
Else mySpecifiedPath/foo.dll will be loaded.
Clarification: The back-up dll should only be loaded if no version of the dll is found in the standard LoadLibrary search paths.
Leaving the old answer at the bottom and adding a new one at the top:
The combination of delay-loading and the delay-load Failure Hook as described at provides a nice way to handle this.
Register the failure hook that loads the back-up dll before using any symbol from the library.
#include <Windows.h>
#include "foo.h"
#include <delayimp.h>
//access to set the failure hook
ExternC PfnDliHook __pfnDliFailureHook2;
const char* dllName = "foo.dll";
const char* dllBackupPath = "pathToBackup\\foo.dll";
FARPROC WINAPI DelayLoadHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
//if the failure was failure to load the designated dll
if (dliNotify == dliFailLoadLib &&
strcmp(dllName, pdli->szDll) == 0 &&
pdli->dwLastError == ERROR_MOD_NOT_FOUND)
{
printf("loading back-up dll\n");
//return the successfully loaded back-up lib,
//or 0, the LoadLibrary fails here
HMODULE lib = LoadLibraryA(dllBackupPath);
return (FARPROC)lib;
}
return 0;
}
int main()
{
//set the Failure Hook
__pfnDliFailureHook2 = &DelayLoadHook;
//when this function is called the library will be loaded
//from standard paths. If it is not found the Failure Hook
//set above will be called.
int test = ::intReturningFuncFromFooDll();
printf("%d", test);
getchar();
return 0;
}
===========old answer below==============
Looks like what I was looking for is delay-loading, as mentioned in the comment by IInspectable. I found information regarding this:
Linker Support for Delay-Loaded DLLs
Here is some code demonstrating the usage I mentioned in the original post:
//load the dll using the normal search
HMODULE lib = LoadLibrary( L"foo.dll" );
//if unsuccessful, try a specified path
if (lib == NULL)
{
LoadLibrary( L"mySpecifiedPath/foo.dll" );
}
if (lib == NULL)
{
//make sure that the library is not used,
//or exit the application, as it was not found
}
Thanks for the help!
edit to old answer: This dynamic loading would be used before any symbol from the library is used. The delay loaded fills out the symbol addresses using the module loaded here the first time a symbol from the library is accessed.
Looking at the Dynamic-Link Library Search Order documentation, it should be obvious, that the final location searched is the PATH environment variable. Applying that knowledge, the easiest solution that meets all your requirements is to append the backup location to the PATH variable.
This could be done in two ways:
An external launcher: The CreateProcess API call allows an application, to pass a custom environment to the new process through the lpEnvironment argument. The current process' environment block can be queried by calling GetEnvironmentStrings.
Enable delay-loading of the desired DLL(s) using the /DELAYLOAD linker option, and modify the process' environment at application startup. After retrieving the PATH environment variable (using GetEnvironmentVariable), it can be modified and updated in the environment block by calling SetEnvironmentVariable.

All Typescript Variables Are Accessible In All Files?

File A:var x: number = 5;
File B:var x = function (): number { return 5; };
Error:Subsqeuent variable declarations must have same type.
Removing all references (///<reference path='/Scripts/example.ts' />) has NO effect on my project. Everything still compiles, Intellisense still works. To my understanding, this is definitely not intended behavior. Any variable declared in any file is available in all files, like the one that caused the error above. I've been aware something weird was going on but I'm about to embark on a project where File B is going to have lots of variables of the same name as A, but they must remain separate. So this is an issue. But I can't find any reading on what's going on here. Everyone says you control Intellisense with the reference directive and you must use it.
Can't find anything about this in Project Settings>TypeScript, nor Tools>Options.
It's expected behavior. Use modules to separate variables in different files
// file 1
module First {
var x = 3;
}
// file 2
module Second {
var x = function (): number { return 5; };
}
See also TypeScript module documentation and
javascript module pattern
Another option would be using AMD or CommonJS compilation option of the TypeScript, see this article

Imported global variable from dll not updated

I am exporting a global variable from a dll using __declspec(dllexport) and importing the same in the client exe using __declspec(dllimport).
The global variable in the dll is being updated with time in a separate thread. I want to receive this updated data in my client .exe, but I am not getting it. What I get is the only initial value of the global variable every time I read the data using a timer in the client exe.
What is the explanation of such a behavior? and what can I do to achieve what I want to achieve? Is there an option without including get() and set() exported functions from the dll?
Here is the code that is exported from dll:
typedef struct{
int iTotalQueues;
int iCurrentQueue;
wchar_t szQueueName[100];
}UPDATE_STATUS_DATA;
__declspec(dllexport) UPDATE_STATUS_DATA UpdateStatusData;
This structure members are updated in a loop for a long time. The updating code is in the dll itself.
Here is the code that is imported in the exe:
typedef struct{
int iTotalQueues;
int iCurrentQueue;
wchar_t szQueueName[100];
}UPDATE_STATUS_DATA;
__declspec(dllimport) UPDATE_STATUS_DATA UpdateStatusData;
I am reading this data inside a timer response and not getting the updated values.
The code in your question as you would expect when built into a simple test project. So, here are the two explanations that I can concoct:
You are taking a copy of UpdateStatusData in your executable. And so the changes to the value of UpdateStatusData made in the DLL do not get reflected in the copy.
Your DLL is, for some reason, not modifying the struct.

Including DirectShow library into Qt for video thumbnail

I'm trying to implement http://msdn.microsoft.com/en-us/library/dd377634%28v=VS.85%29.aspx on Qt, to generate a poster frame/thumbnail for video files.
I have installed both Windows Vista and Windows 7 SDK. I put:
#include "qedit.h"
in my code (noting there is also one in C:\Qt\2010.04\mingw\include), I add:
win32:INCLUDEPATH += $$quote(C:/WindowsSDK/v6.0/Include)
to my *.pro file. I compile and get " error: sal.h: No such file or directory". Finding this in VC++ I add
win32:INCLUDEPATH += $$quote(C:/Program Files/Microsoft Visual Studio 10.0/VC/include)
And now have 1400 compile errors. So, I abandon that and just add:
win32:LIBS += C:/WindowsSDK/v7.1/Lib/strmiids.lib
to my *.pro file and try to run (without including any headers):
IMediaDet mediadet;
But then I get "error: IMediaDet: No such file or directory".
#include "qedit.h"
gives me the same error (it looks like it's pointing to the Qt version) and
#include "C:/WindowsSDK/v6.0/Include/qedit.h"
goes back to generating 1000's of compile errors.
Sigh, so much trouble for what should be 10 lines of code...
Thanks for your comments and help
Since you say you are "a C++/Qt newbie" then I suspect that the real issue may be that you are attempting to load the library yourself rather than simply linking your application to it?
To link an external library into your application with Qt all you need to do is modify the appropriate .pro file. For example if the library is called libfoo.dll you just add
LIBS += -L/path/to/lib -lfoo
You can find more information about this in the relevant section of the qmake manual. Note that qmake commonly employs Unix-like notation and transparently does the right thing on Windows.
Having done this you can include the library's headers and use whatever classes and functions it provides. Note that you can also modify the project file to append an include path to help pick up the headers eg.
INCLUDEPATH += /path/to/headers
Again, more information in the relevant section of the qmake manual.
Note that both these project variables work with relative paths and will happily work with .. to mean "go up a directory" on all platforms.
Note that qedit.h requires dxtrans.h, which is part of DirectX9 SDK.
You can find dxtrans.h in DirectX SDK from August 2006. Note that dxtrans.h is removed from newer DirectX SDKs.
Do you have access to the source of the external library? The following assumes that you do.
What I do when I need to extract a class from a library with only functions resolved, is to use a factory function in the library.
// Library.h
class SomeClass {
public:
SomeClass(std::string name);
// ... class declaration goes here
};
In the cpp file, I use a proxy function outside the extern "C" when my constructor requires C++ parameters (e.g. types such as std::string), which I pass as a pointer to prevent the compiler from messing up the signature between C and C++. You can avoid the extra step if your constructor doesn't require parameters, and call new SomeClass() directly from the exported function.
// Library.cpp
#include "Library.h"
SomeClass::SomeClass(std::string name)
{
// implementation details
}
// Proxy function to handle C++ types
SomeClass *ImplCreateClass(std::string* name) { return new SomeClass(*name); }
extern "C"
{
// Notice the pass-by-pointer for C++ types
SomeClass *CreateClass(std::string* name) { return ImplCreateClass(name); }
}
Then, in the application that uses the library :
// Application.cpp
#include "Library.h"
typedef SomeClass* (*FactoryFunction)(std::string*);
// ...
QLibrary library(QString("MyLibrary"));
FactoryFunction factory = reinterpret_cast(library.resolve("CreateClass"));
std::string name("foobar");
SomeClass *myInstance = factory(&name);
You now hold an instance of the class declared in the library.

Resources