Exporting a function in a DLL using Microsoft Visual C++ 6.0

Background

There is a function written in C (not necessarily in C++). The function is a part of the source code of a DLL, namely PreciseLanczosDLL.dll. There is a C# program, namely PreciseLanczosSharp, which wants to consume the function in the DLL.

Requirement

The function needs to be exported in a form in which the C# program can access it. In addition, the exported function name should be easy to understand.

Investigation and result

I tried the following two ways:
a1. Using a __declspec(dllexport) declaration in the header file.
a2. Using a .DEF file.

In the C# project, I added a copy command to the pre-build steps to copy the dll file to the target directory of the C# file:

copy $(ProjectDir)..\PreciseLanczosDLL\Release\PreciseLanczosDLL.dll $(ProjectDir)$(OutDir)

This way, each time the project is rebuilt, the dll file is automatically copied and can be used.

I simply used the following declaration in the header file to export the function from the dll:

__declspec(dllexport) int WINAPI fnPreciseLanczosDLL(void);

I found that, for situation a1, I couldn't simply use the following C# source code to load the function:

[DllImport("PreciseLanczosDLL.dll", CallingConvention=CallingConvention.StdCall,
    SetLastError=false)]
public static extern int fnPreciseLanczosDLL();

The exception would be like:

Unhandled Exception: System.EntryPointNotFoundException: Unable to find an entry
 point named 'fnPreciseLanczosDLL' in DLL 'PreciseLanczosDLL.dll'.

What tool can I use to look into the generated dll? I found Dependency Walker. I then then used Dependency Walker (version 2.2) to look at the dll as the compilation result. I found that the exported function is not called "fnPreciseLanczosDLL". Instead, it's called "?nPreciseLanczosDLL@@3HA".

I think that the function name might have been mangled for use with C++. As we all know, C++ allows function overloading while C doesn't. To allow function overloading, a function with the same name can have multiple declarations and implementations based on the signature, which consists of both the function name and the list of parameter types. When exporting such a function to a dll or to a debugger, it must be mangled so that each function declaration has its own mangled name.

Then I tried forcing Visual C++ compiler not to mangle the name. I successfully did that, by using the following lines of code in the header file:

extern "C" {
    __declspec(dllexport) int WINAPI fnPreciseLanczosDLL(void);
}

However, as Dependency Walker shows it, the unmangled name in the DLL is "_fnPreciseLanczosDLL@0", rather than "fnPreciseLanczosDLL".

When I import the function in the C# program, I have to use the following source code:

[DllImport("PreciseLanczosDLL.dll", CallingConvention=CallingConvention.StdCall,
    SetLastError=false, EntryPoint="_fnPreciseLanczosDLL@0")]
public static extern int fnPreciseLanczosDLL();

This is ugly. So I tried method a2. I used a .DEF file, and commented out the __declspec(dllexport) line in the header file (later I found that leaving the __declspec(dllexport) line in the file is still OK--it just won't have any effect). The .DEF file looks like:

LIBRARY PreciseLanczosDLL
DESCRIPTION "PreciseLanczos Library"
EXPORTS
    fnPreciseLanczosDLL @1

Now, Dependency Walker shows the expected exporting name: fnPreciseLanczosDLL. Its ordinal is 1 but this is not a part of the function name. Now the C# code is also clean:

[DllImport("PreciseLanczosDLL.dll", CallingConvention=CallingConvention.StdCall,
    SetLastError=false)]
public static extern int fnPreciseLanczosDLL();

The investigation shows good result.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值