导航:首页 > 源码编译 > 怎么把sln编译成dll文件

怎么把sln编译成dll文件

发布时间:2023-05-29 23:46:05

A. 如何编译生成dll

使用VC下的cl和link手工创建dll并实现函数导入

1、创建dll头文件:
/*
* dllmain.h
*/
#ifndef _DLLMAIN_H
#define _DLLMAIN_H

int getNumber();

#endif

2、创建dll源文件:
/*
* dllmain.c
*/
#include "dllmain.h"

int getNumber()
{
return 10;
}

3、 创建def文件:
; export.def
LIBRARY MY_DLLMAIN ; MY_DLLMAIN 将成为生成的dll的名称
EXPORTS
getNumber @1 ; 这个名称即为函数的实际导出名称 @1为函数的导出编号

4、生成dll文件:
cl dllmain.c /c
link /def:export.def /dll dllmain.obj

这时,工程中已经包含了 dllmain.h dllmain.c export.def dllmain.obj dllmain.lib dllmain.exp MY_DLLMAIN.dll 其中,后4个文件是编译链接过程中生成的文件

5、创建dlltest.c:
/*
* dlltest.c
*/
#include <stdio.h>
#include "dllmain.h" //dll库的头文件

#pragma comment(lib,"dllmain.lib") //dllmain.lib即是上一步生成的文件

int main()
{
printf("%dn",getNumber());
}

6、编译、链接dlltest.c
cl dlltest.c /c
link dlltest.obj

注意:这里dllmain.lib和dllmain.h应该和dlltest.c在同一个目录中。此步的结果将生成 dlltest.exe

7、运行:
dlltest

这时,系统将载入my_dllmain.dll这个动态链接库,将调用其中的getNubmer函数。

B. 在怎样情况下把代码编译成dll文件

如果使用的是VS,可以进行如下操作:
打开VS, 文件-新建-新建项目-其他语言-Visual C++ - Win32 控制台应用程序。
单击确定后,弹出对话框,按照对话框“下一步”提示进行操作。
将要编译的C文件拷贝到CreateDLL项目中,.h文件就放到头文件夹的目录下,.c文件放到源文件目录下,注意后缀名为.c的文件都要改成.cpp,否则编译会出错。
注意:申明函数时必须参照上图红框标示出来的规则,在Function.cpp文件中必须要引入对应的#include CreateDLL.h。
选中所有需要编译成dll的cpp文件,右键-属性-预编译头-不使用预编译头,然后选择 “生成”即可,这样在项目的Debug文件夹下面便可找到CreateDLL.dll文件

C. c#使用命令行编译生成dll文件

C#使用csc.exe编译程序,csc使用/target:library(缩写: /t:library)参数生成Dll文件。
其它参数如下:
Visual C# 编译器选项
- 输出文件 -
/out:<文件> 指定输出文件名(默认值: 包含主类的文件或第一个文件的基名称)
/target:exe 生成控制台可执行文件(默认) (缩写: /t:exe)
/target:winexe 生成 Windows 可执行文件 (缩写: /t:winexe)
/target:library 生成库 (缩写: /t:library)
/target:mole 生成能添加到其他程序集的模块 (缩写: /t:mole)
/target:appcontainerexe 生成 Appcontainer 可执行文件 (缩写: /t:appcontainerexe)
/target:winmdobj 生成 WinMDExp 使用的 Windows 运行时中间文件 (缩写: /t:winmdobj)
/doc:<文件> 要生成的 XML 文档文件
/platform:<字符串> 限制可以在其上运行此代码的平台: x86、Itanium、x64、arm、anycpu32bitpreferred 或 anycpu。默认值为 anycpu。

- 输入文件 -
/recurse:<通配符> 根据通配符规范,包括当前目录和子目录下的所有文件
/reference:<别名>=<文件> 使用给定的别名从指定的程序集文件引用元数据 (缩写: /r)
/reference:<文件列表> 从指定的程序集文件引用元数据 (缩写: /r)
/addmole:<文件列表> 将指定的模块链接到此程序集中
/link:<文件列表> 嵌入指定的互操作程序集文件中的元数据 (缩写: /l)

- 资源 -
/win32res:<文件> 指定 Win32 资源文件(.res)
/win32icon:<文件> 对输出使用此图标
/win32manifest:<文件> 指定 Win32 清单文件(.xml)
/nowin32manifest 不包括默认 Win32 清单
/resource:<资源信息> 嵌入指定的资源 (缩写: /res)
/linkresource:<资源信息> 将指定的资源链接到此程序集 (缩写: /linkres)
其中 resinfo 的格式是 <file>[,<string name>[,public|private]]

- 代码生成 -
/debug[+|-] 发出调试信息
/debug:{full|pdbonly} 指定调试类型(“full”是默认类型,可以将调试程序附加到正在运行的程序)
/optimize[+|-] 启用优化 (缩写: /o)

- 错误和警告 -
/warnaserror[+|-] 将所有警告报告为错误
/warnaserror[+|-]:<警告列表> 将特定警告报告为错误
/warn:<n> 设置警告等级(0-4) (缩写: /w)
/nowarn:<警告列表> 禁用特定的警告消息

- 语言 -
/checked[+|-] 生成溢出检查
/unsafe[+|-] 允许“不安全”代码
/define:<符号列表> 定义条件编译符号 (缩写: /d)
/langversion:<字符串> 指定语言版本模式: ISO-1、ISO-2、3、4、5 或 Default

- 安全性 -
/delaysign[+|-] 仅使用强名称密钥的公共部分对程序集进行延迟签名
/keyfile:<文件> 指定强名称密钥文件
/keycontainer:<字符串> 指定强名称密钥容器
/highentropyva[+|-] 启用高平均信息量的 ASLR

- 杂项 -
@<文件> 有关更多选项,请阅读响应文件
/help 显示此用法信息 (缩写: /?)
/nologo 取消编译器版权信息
/noconfig 不要自动包含 CSC.RSP 文件

- 高级 -
/baseaddress:<地址> 要生成的库的基址
/bugreport:<文件> 创建“Bug 报告”文件
/codepage:<n> 指定打开源文件时要使用的代码页
/utf8output 以 UTF-8 编码格式输出编译器消息
/main:<类型> 指定包含入口点的类型(忽略所有其他可能的入口点) (缩写: /m)
/fullpaths 编译器生成完全限定路径
/filealign:<n> 指定用于输出文件节的对齐方式
/pdb:<文件> 指定调试信息文件名(默认值: 扩展名为 .pdb 的输出文件名)
/errorendlocation 输出每个错误的结束位置的行和列
/preferreilang 指定首选输出语言名称。
/nostdlib[+|-] 不引用标准库(mscorlib.dll)
/subsystemversion:<字符串> 指定此程序集的子系统版本
/lib:<文件列表> 指定要在其中搜索引用的附加目录
/errorreport:<字符串> 指定如何处理内部编译器错误: prompt、send、queue 或 none。默认值为 queue。
/appconfig:<文件> 指定一个包含程序集绑定设置的应用程序配置文件
/moleassemblyname:<字符串> 此模块所属程序集的名称

D. c语言写的程序怎么样生成.dll文件

dll制作步骤:
1.编写dll函数实现源代码hello.c

#include

int say_hello(char* name)
{
printf( "hello %s\n ", name);
return 1;
}

2.编写dll函数输出定义文件hello.def.

LIBRARY hello
EXPORTS
say_hello @1

3.编译dll源码,生成dll,lib文件.

3.1 新建命令行窗口
3.2 设置PATH ?? INCLUDE ?? LIB 3个环境变量.

SET PATH=K:\vcnet\vc7\bin;%PATH%
SET INCLUDE=K:\vcnet\vc7\include;%INCLUDE%
SET LIB=K:\vsnet\Vc7\lib;%LIB%

3.3 编译hello.c

cd K:\Source\dllsample (hello.c和hello.def所在目录)
cl /c hello.c

3.4 链接hello.obj,生成hello.dll,hello.lib两个文件.

link /def:hello.def /dll hello.obj

4.测试dll函数.

4.1 编写测试代码 test.c

extern int say_hello(char* name);
int main(int argc,char** argv)
{
say_hello( "robbie ");
return 0;
}

4.2 编译测试代码test.c

cl /c test.c

4.3 链接test.obj和 hello.lib,生成可执行文件test.exe

link test.obj hello.lib

4.4 运行test.exe,屏幕输出:

hello robbie

至此,一个dll构造完毕.

E. 怎么把sln编译成类库

以Add_new一个函数为例:
1. New--projects--MFC AppWizard(dll)--Regular DLL using shared MFC DLL //取名为MFC_dll
2. def文件中添加:函数名(Add_new)
3. h文件中添加:外部函数声明//求和函数,函数名为Add_new
extern "C" __declspec(dllexport) int __stdcall Add_new(int a,int b);
4. cpp文件中添加: 外部函数实现
extern "C" __declspec(dllexport) int __stdcall Add_new(int a,int b)
{
return a+b;
}
5. build--set active configuration--win32 release--ok
6. 生成
7. 根目录下release文件夹中dll,lib与根目录下h文件即为所需

F. 应用程序如何转换成DLL格式

是c++的,你可以用c++来编写首先创建一个动态库的工程。
然后把你原程序中要用的函数和变量封装成一个类,假如类名为DLLClass
然后在DLL.h(这里假设文件名为DLL)文件中添加如下代码:
#ifdef DLL_API
#else
#define DLL_API extern "C" _declspec(dllimport)
#endif

class DLL_API DLLClass{//把类中的函数、变量声明完};

然后在DLL.cpp文件中添加如下代码:
#define DLL1_API extern "C" _declspec(dllexport)
#include "Dll.h"
#include <Windows.h>

然后实现类中的函数即可。
最后编译,生成DLL.lib 和DLL.dll的文件,把这两个文件放到你要加载的程序文件夹下即可。

G. 如何编译生成dll

创建DLL工程
这里,我们为了简要说明DLL的原理,我们决定使用最简单的编译环境VC6.0,如下图,我们先建立一个新的Win32 Dynamic-Link Library工程,名称为“MyDLL”,在Visual Studio中,你也可以通过建立Win32控制台程序,然后在“应用程序类型”中选择“DLL”选项,

点击确定,选择“一个空的DLL工程”,确定,完成即可。

一个简单的dll
在第一步我们建立的工程中建立一个源码文件”dllmain.cpp“,在“dllmain.cpp”中,键入如下代码

[cpp] view plain
#include <Windows.h>
#include <stdio.h>

BOOL APIENTRY DllMain(HMODULE hMole, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
printf("DLL_PROCESS_ATTACH\n");
break;
case DLL_THREAD_ATTACH:
printf("DLL_THREAD_ATTACH\n");
break;
case DLL_THREAD_DETACH:
printf("DLL_THREAD_DETACH\n");
break;
case DLL_PROCESS_DETACH:
printf("DLL_PROCESS_DETACH\n");
break;
}
return TRUE;
}
之后,我们直接编译,即可以在Debug文件夹下,找到我们生成的dll文件,“MyDLL.dll”,注意,代码里面的printf语句,并不是必须的,只是我们用于测试程序时使用。而DllMain函数,是dll的进入/退出函数。

实际上,让线程调用DLL的方式有两种,分别是隐式链接和显式链接,其目的均是将DLL的文件映像映射进线程的进程的地址空间。我们这里只大概提一下,不做深入研究,如果感兴趣,可以去看《Window高级编程指南》的第12章内容。
隐式链接调用
隐士地链接是将DLL的文件影响映射到进程的地址空间中最常用的方法。当链接一个应用程序时,必须制定要链接的一组LIB文件。每个LIB文件中包含了DLL文件允许应用程序(或另一个DLL)调用的函数的列表。当链接器看到应用程序调用了某个DLL的LIB文件中给出的函数时,它就在生成的EXE文件映像中加入了信息,指出了包含函数的DLL文件的名称。当操作系统加载EXE文件时,系统查看EXE文件映像的内容来看要装入哪些DLL,而后试图将需要的DLL文件映像映射到进程的地址空间中。当寻找DLL时,系统在系列位置查找文件映像。

1.包含EXE映像文件的目录
2.进程的当前目录
3.Windows系统的目录
4.Windows目录
5.列在PATH环境变量中的目录

这种方法,一般都是在程序链接时控制,反映在链接器的配置上,网上大多数讲的各种库的配置,比如OPENGL或者OPENCV等,都是用的这种方法

显式链接调用
这里我们只提到两种函数,一种是加载函数
[cpp] view plain
HINSTANCE LoadLibrary(LPCTSTR lpszLibFile);

HINSTANCE LoadLibraryEx(LPCSTR lpszLibFile,HANDLE hFile,DWORD dwFlags);
返回值HINSTANCE值指出了文件映像映射的虚拟内存地址。如果DLL不能被映进程的地址空间,函数就返回NULL。你可以使用类似于

[cpp] view plain
LoadLibrary("MyDLL")
或者

[cpp] view plain
LoadLibrary("MyDLL.dll")
的方式进行调用,不带后缀和带后缀在搜索策略上有区别,这里不再详解。

显式释放DLL

在显式加载DLL后,在任意时刻可以调用FreeLibrary函数来显式地从进程的地址空间中解除该文件的映像。
[cpp] view plain
BOOL FreeLibrary(HINSTANCE hinstDll);
这里,在同一个进程中调用同一个DLL时,实际上还牵涉到一个计数的问题。这里也不在详解。
线程可以调用GetMoleHandle函数:

[cpp] view plain
GetMoleHandle(LPCTSTR lpszMoleName);
来判断一个DLL是否被映射进进程的地址空间。例如,下面的代码判断MyDLL.dll是否已被映射到进程的地址空间,如果没有,则装入它:

[cpp] view plain
HINSTANCE hinstDll;
hinstDll = GetMoleHandle("MyDLL");
if (hinstDll == NULL){
hinstDll = LoadLibrary("MyDLL");
}
实际上,还有一些函数,比如 GetMoleFileName用来获取DLL的全路径名称,FreeLibraryAndExitThread来减少DLL的使用计数并退出线程。具体内容还是参见《Window高级编程指南》的第12章内容,此文中不适合讲太多的内容以至于读者不能一下子接受。

DLL的进入与退出函数

说到这里,实际上只是讲了几个常用的函数,这一个小节才是重点。
在上面,我们看到的MyDLL的例子中,有一个DllMain函数,这就是所谓的进入/退出函数。系统在不同的时候调用此函数。这些调用主要提供信息,常常被DLL用来执行进程级或线程级的初始化和清理工作。如果你的DLL不需要这些通知,就不必再你的DLL源代码中实现此函数,例如,如果你创建的DLL只含有资源,就不必实现该函数。但如果有,则必须像我们上面的格式。
DllMain函数中的ul_reason_for_call参数指出了为什么调用该函数。该参数有4个可能值: DLL_PROCESS_ATTACH、DLL_THREAD_ATTACH、DLL_THREAD_DETACH、DLL_PROCESS_DETACH。
其中,DLL_PROCESS_ATTACH是在一个DLL首次被映射到进程的地址空间时,系统调用它的DllMain函数,传递的ul_reason_for_call参数为DLL_PROCESS_ATTACH。这只有在首次映射时发生。如果一个线程后来为已经映射进来的DLL调用LoadLibrary或LoadLibraryEx,操作系统只会增加DLL的计数,它不会再用DLL_PROCESS_ATTACH调用DLL的DllMain函数。
而DLL_PROCESS_DETACH是在DLL被从进程的地址空间解除映射时,系统调用它的DllMain函数,传递的ul_reason_for_call值为DLL_PROCESS_DETACH。我们需要注意的是,当用DLL_PROCESS_ATTACH调用DLL的DllMain函数时,如果返回FALSE,说明初始化不成功,系统仍会用DLL_PROCESS_DETACH调用DLL的DllMain。因此,必须确保没有清理那些没有成功初始化的东西。
DLL_THREAD_ATTACH:当进程中创建一个线程时,系统察看当前映射到进程的地址空间中的所有DLL文件映像,并用值DLL_THREAD_ATTACH调用所有的这些DLL的DllMain函数。该通知告诉所有的DLL去执行线程级的初始化。注意,当映射一个新的DLL时,进程中已有的几个线程在运行,系统不会为已经运行的线程用值DLL_THREAD_ATTACH调用DLL的DllMain函数。
而DLL_THREAD_DETACH,如果线程调用ExitThread来终结(如果让线程函数返回而不是调用ExitThread,系统会自动调用ExitThread),系统察看当前映射到进程空间的所有DLL文件映像,并用值DLL_THREAD_DETACH来调用所有的DLL的DllMain函数。该通知告诉所有的DLL去执行线程级的清理工作。
这里,我们需要注意的是,如果线程的终结是因为系统中的一个线程调用了TerminateThread,系统就不会再使用DLL_THREAD_DETACH来调用DLL和DllMain函数。这与TerminateProcess一样,不再万不得已时,不要使用。
下面,我们贴出《Window高级编程指南》中的两个图来说明上述四种参数的调用情况。

好的,介绍了以上的情况,下面,我们来继续实践,这次,建立一个新的空的win32控制台工程TestDLL,不再多说,代码如下:

[cpp] view plain
#include <iostream>
#include <Windows.h>
using namespace std;

DWORD WINAPI someFunction(LPVOID lpParam)
{
cout << "enter someFunction!" << endl;
Sleep(1000);
cout << "This is someFunction!" << endl;
Sleep(1000);
cout << "exit someFunction!" << endl;
return 0;
}

int main()
{
HINSTANCE hinstance = LoadLibrary("MyDLL");
if(hinstance!=NULL)
{
cout << "Load successfully!" << endl;
}else {
cout << "Load failed" << endl;
}
HANDLE hThread;
DWORD dwThreadId;

cout << "createThread before " << endl;
hThread = CreateThread(NULL,0,someFunction,NULL,0,&dwThreadId);
cout << "createThread after " << endl;
cout << endl;

Sleep(3000);

cout << "waitForSingleObject before " << endl;
WaitForSingleObject(hThread,INFINITE);
cout << "WaitForSingleObject after " << endl;
cout << endl;

FreeLibrary(hinstance);
return 0;
}

代码很好理解,但是前提是,你必须对线程有一定的概念。另外,注意,我们上面编译的获得的“MyDLL.dll"必须拷贝到能够让我们这个工程找到的地方,也就是上面我们提到的搜索路径中的一个地方。
这里,我们先贴结果,当然,这只是在我机器上其中某次运行结果。

有了上面我们介绍的知识,这个就不是很难理解,主进程在调用LoadLibrary时,用DLL_PROCESS_ATTACH调用了DllMain函数,而线程创建时,用DLL_THREAD_ATTACH调用了DllMain函数,而由于主线程和子线程并行的原因,可能输出的时候会有打断。但是,这样反而能让我们更清楚的理解程序。

H. 如何在windows环境下将.so编译成.dll如果不行,在linux下的具体编译过程是怎样的望高手回答。。谢!

.so文件就已经是经过编译的C程序

而.dll文件是编译好的动态链接库文件,需要用rundll32.exe来执行,或者载入shell执行。

所以.so和.dll不能互换。

在linux下面直接用gcc编译器就能编译。

命令格式:

gcc 文件名 C源码文件名

例:

gcc 123.so 123.c

===========================================
.dll的就是已经编译成功的了,不能再被编译。
就像生孩子,已经是女孩了,你还能捅回去再换
个男孩出来?
===========================================

阅读全文

与怎么把sln编译成dll文件相关的资料

热点内容
手机银行app利率是什么意思 浏览:208
博途scl编译信号或精度丢失 浏览:630
静态编译失败的原因 浏览:233
西安人社app为什么注册不了 浏览:24
linux下root密码修改 浏览:699
苹果11watchapp有什么用 浏览:471
linux文件系统集群 浏览:747
大奥电视剧观看顺序 浏览:478
深圳程序员真实工资是多少 浏览:517
androidgetbytes 浏览:706
争鸣pdf 浏览:968
饥荒联机版如何直连服务器 浏览:121
妈妈的朋友崇石演过什么电影 浏览:868
qq邮箱如何查看服务器的地址 浏览:800
穿越到各大电影世界 浏览:584
青海集群服务器云空间 浏览:924
韩剧不能看有什么app可以代替 浏览:585
用气球和黏土做解压玩具 浏览:187
天地23tⅹt 浏览:784
恐怖电影观看免费推荐 浏览:4