Dumpbin shows strange method name (generating exporting function in MS Visual C++) - dll

I have created new Win32 project in my VS and have selected Dynamic Library ( *.dll ) for this aim.
I have defined some exporting function in the main file:
__declspec(dllexport)
int TestCall(void)
{
int value = 4 / 2;
std::cout << typeid(value).name() << std::endl;
return value;
}
__declspec(dllexport)
void SwapMe(int *first, int *second)
{
int tmp = *first;
*first = *second;
*second = tmp;
}
When I've looked at the dumpin /exports, I've got:
ordinal hint RVA name
1 0 00001010 ?SwapMe##YAXPEAH0#Z
2 1 00001270 ?TestCall##YAHXZ
I'm calling in the C# version like this:
[DllImport(#"lib1.dll", EntryPoint = "?TestCall##YAHXZ",
CallingConvention = CallingConvention.Cdecl)]
static extern int TestCall();
It's not the correct form of using exported methods. Where did I fail with generating such names for exporting-methods in the C++ dll project?

This is normal, the C++ compiler applies name decoration to functions. The C++ language supports function overloading, much like C# does. So you could write a Foo(int) and a Foo(double) function. Clearly they cannot both be exported as a function named "Foo", the client code wouldn't know which one to call. So the extra characters encode the name so that it is unique for the overload.
You can turn that off by declaring the function extern "C", the C language doesn't support overloading so doesn't require the same kind of decoration.
But it is actually better if you don't. Because it is also an excellent way to catch mistakes. Like changing the function declaration in your C++ code but forgetting to modify the pinvoke declaration in your C# code. You will now get an easy to diagnose "Entrypoint not found" exception instead of a non-descriptive and very hard to diagnose AccessViolationException. Which doesn't necessarily have to be raised in the C++ code, the stack imbalance can also crash your C# code. Looking up the decorated name is a bit painful however, improve that by asking the linker to create a map file (/MAP option).

use extern "C" to specify the linkage to avoid the name mangling:
extern "C" __declspec(dllexport) int TestCall(void);
extern "C" __declspec(dllexport) void SwapMe(int *first, int *second);

Related

Objective-C float #define not accessible in Swift4

I am migrating code from Objective-C to Swift 4.0. Here I have some float #define constants related to my deviceHeight in Specific Objective-C header class. While accessing this #define giving error "Use of unresolved identifier". When I use Objective-C string #define identifier it's easily accessible within Swift class.
Not accessible in Swift4
#define PHONE_IPHONE10 PHONE_UISCREEN_HEIGHT==812.0f
Accessible in Swift4
#define ERROR #"Some error occured. Please try later."
Help me with your comments or solution.
The reason this imports to Swift...
#define ERROR #"Some error occured. Please try later."
...is that it’s semantically equivalent to a constant declaration. That is, it permanently associates that string-literal value with the name ERROR. The Swift compiler recognizes that you’re using the C preprocessor to define a constant, and translates it to a Swift constant.
(Even though you could—and probably should—define C global constants without the preprocessor, Swift recognizes that there’s a long tradition of using #define instead, and imports it anyway.)
The reason this doesn’t import to Swift...
#define PHONE_IPHONE10 PHONE_UISCREEN_HEIGHT==812.0f
...is that this is a preprocessor macro. It doesn’t statically map a name to a value. Instead, it tells C that wherever it sees your name PHONE_IPHONE10, it should substitute the expression PHONE_UISCREEN_HEIGHT==812.0f. Presumably PHONE_UISCREEN_HEIGHT is itself a macro, so the whole thing expands to a chain of method calls and an equality comparison.
Swift itself doesn’t do preprocessor macros, or anything like such, so it doesn’t import them from C.
A close equivalent would be to redefine this logic using a computed property or function (and the idiomatic way to do that in Swift would be as a static member on a type, not a global symbol). Something like this:
extension UIDevice {
class var isMaybeiPhoneX: Bool {
return false // or some logic based on UIScreen.main.size
}
}
But be warned, the whole idea of conditionally changing your app’s UI or behavior based on a specific screen height check is fraught with peril. Tried Auto Layout?
To achieve similar functionality I created Constants.swift file with this structure:
struct Constants {
struct phoneHeights {
static let PHONE_UISCREEN_HEIGHT = 812.0
//some others consts
}
struct iPhoneX {
static let statusBarHeight: CGFloat = 44
//some others consts
}
}
Or simply:
struct Constants {
static let PHONE_UISCREEN_HEIGHT = 812.0
static let statusBarHeight: CGFloat = 44
}
And for type safety in Swift, you can read here.

I am about to use dlopen() to open shared object. Do I need to include corresponding headers if shared object?

I have to use dlopen() and access functions from shared object in my code. Do I need to include headers of corresponding functions of shared object ?
Because of the way dlopen() and dlsym() operate, I don't see how that would accomplish anything. Very roughly speaking, dlopen() copies the library binary into your program space and adds the addresses of its exported symbols (i.e. global functions & variables) to your program's symbol table.
Because the library was not linked to your program at compile-time, there's no way your code could possibly know the instruction addresses of these new functions tacked on at run-time. The only way to access a run-time dynamically linked symbol is via a pointer obtained from dlsym().
You have to create a function pointer for each and every library definition that you want to use. If you want to call them like regular functions, in C-language you can manually typedef type definitions for the function pointers, specifying their parameters and return values, then you can call the pointers just like regular functions. But note that you have to define all of these manually. Including the library header doesn't help.
In C++ I think there are issues with storing dlsym() output in a typedef'd pointer due to stricter standards, but this should work in C:
addlib.c (libaddlib.dylib):
int add(int x, int y) {
return x+y;
}
myprogram.c:
#include <stdio.h>
#include <dlfcn.h>
typedef int (*add_t)(int, int);
int main() {
void *lib_handle;
add_t add; // call this anything you want...it's a pointer, it doesn't care
lib_handle = dlopen("libaddlib.dylib", RTLD_NOW);
if (lib_handle == NULL) {
// error handling
}
add = (add_t)dlsym(lib_handle, "add");
if (add == NULL) {
// error handling
}
printf("Sum is %d\n", add(17, 23));
dlclose(lib_handle); // remove library from address space
return 0;
}
(Update: I compiled the dylib and myprogram...it works as expected.)

Working with structures in C++/CLI

I have following code
ref class A
{
typedef ref struct All
{
std::string x;
}All_t;
};
in my program I am using it in following manner
A::All_t t;
t.X = "H";
This declaration throwing error as
error C4368: cannot define 'x' as a member of managed 'A::All': mixed types are not supported
I understand that I am declaring native varible inside managed code which is not allowed but now I would like to know changes I will need to make to make my structure suitable to managed project.
Thanks.
I'm assuming you originally had std::string x; not std::string *x (since using the pointer to string does not generate that error). You are not allowed to directly embed a native type in a managed type, but you are allowed to indirectly have one (via a pointer) See:
http://msdn.microsoft.com/en-us/library/xhfb39es(v=vs.80).aspx
After I fixed the compiler errors in your sample, it builds without error:
#include "stdafx.h"
#include <string>
using namespace System;
ref class A
{
public:
typedef ref struct All
{
std::string * x;
}All_t;
};
int main(array<System::String ^> ^args)
{
A::All_t t;
t.x = new std::string("H");
return 0;
}

Objective c wrapper for a c file

I went through quite a number of websites, but everywhere they have given how to write a wrapper for a c++ library.
Now, I have a .c file which i want to integrate to my application. Since Objective c is an objected oriented extension of c, will i actually have to write wrapper for it? if yes, how to do it? if i dont have to, then how to use the c code in my project?
EDIT : ok.. what i have to do is add the file into my project and use the functions? how exactly to do it?? just like normal c call? what if i have to pass parameters?
Let say i have a function which returns a string, first of all how do i call that function? and if it returns a string, can i store that value in a normal NSString?? or should i declare a c string for it??
Thanks in advance
You can simply use your C code as usual:
-(void)writeString:(NSString*)data toFile:(NSString*)filename {
FILE* output = fopen([filename UTF8String], "w");
fprintf(output, "%s", [data UTF8String]);
fclose(output);
}
For other .c files, simply #include the corresponding header. Then, you can just call its functions.
For example, if this was foo.h:
int add(int a, int b);
And foo.c:
#include "foo.h"
int add(int a, int b) {
return a + b;
}
Then in your Objective-C code (Bar.m):
-(int)addA:(int)a andB:(int)b {
return add(a, b);
}
That is basically a wrapper right there. However, wrappers are not needed for C code in Objective-C. Even C++ functions do not need wrappers, as there are .mm files which are Objective-C++ sources.
Edit:
To call C functions with parameters, just call them with parameters. Literally ANY valid C program is also a valid Objective-C program. If it can compile as a .c file, it'll compile as a .m file.
To convert a C string (char*) to an NSString:
const char* myString = "Hello!";
NSString* myNSString = [NSString stringWithUTF8String:myString];

C++/CLI managed wrapper around C static library

Help!
I'm totally exhausted/frustrated with what seems to be a reasonably easy task. I’m not sure what I'm doing wrong; let alone if I'm doing it correct. I'm "required" to use an existing library (a C static library – over 100,000 lines of straight C code) in developing a WPF application (VS 2010, C# 4.0). Oh, and I can't touch the existing C code - use it as is!
I've read so many postings (advanced topics, how-to, etc), yet I'm so new to C++/CLI that it's just not making sense. From what I've read the best approach is to wrap the C static library as follows:
Unmanaged C static library <---> C++/CLI managed wrapper DLL <--->
managed WPF application
This is the stripped down C header file:
/* Call this function to execute a command. */
int issue_command(int command, long param1, long param2);
/* Completion call back function; you must supply a definition. */
extern int command_completed(int command, long param1, long param2);
struct struct_command_str
{
char command_str[10];
char param1_st[2];
char param2_st[2];
char success;
};
/* You must supply definitions to the following extern items. */
extern int command_status;
extern struct struct_command_str command_str;
The problem(s):
What I can’t seem to do correctly is provide a C++/CLI implementation for the call back functions, and the two extern items (command_status and struct command_str).
Can someone provide a sample C++/CLI implementation for the above missing call back functions and externs?
Thanks in advance for your assistance.
in your C++/CLI managed wrapper project, add 2 files :
a .c file :
extern void doSomething();
int command_status = 0;
struct_command_str command_str = { "command1", "p1", "p2", 't' };
int command_completed(int command, long param1, long param2) {
...
command_status = 1;
...
doSomething();
...
command_status = 2;
...
return 3;
}
a cpp file
void doSomethingManagedWrapper() {
...
call managed code
...
}
void doSomething() {
doSomethingManagedWrapper();
}
when you implement these in your c++/cli module, use the same signature shown in the c header file,but prefixed with extern "C".
also put an extern "C" block around the #include of the C header file.