我有两个函数之间的循环依赖.我希望这些函数中的每一个都驻留在它自己的dll中.是否可以使用visual studio构建它?
foo(int i)
{
if (i > 0)
bar(i -i);
}
Run Code Online (Sandbox Code Playgroud)
- >应该编译成foo.dll
bar(int i)
{
if (i > 0)
foo(i - i);
}
Run Code Online (Sandbox Code Playgroud)
- >应该编译成bar.dll
我在visual studio中创建了两个项目,一个用于foo,一个用于bar.通过玩'参考'并编译几次,我设法获得了我想要的dll.我想知道视觉工作室是否提供了一种以干净的方式做到这一点的方法.
如果foo改变了,bar不需要重新编译,因为我只依赖于bar的签名,而不是bar的实现.如果两个dll都有lib存在,我可以将新功能重新编译为两者中的任何一个,整个系统仍然有效.
我尝试这个的原因是我有一个循环依赖的遗留系统,目前静态链接.出于各种原因,我们想要转向dll.我们不想等到清理所有循环依赖项.我正在考虑解决方案,并在linux上用gcc尝试了一些东西,在那里可以做我建议的.因此,您可以拥有两个彼此依赖的共享库,并且可以彼此独立构建.
我知道循环依赖并不是一件好事,但这不是我想要的讨论.
在我开始讨论真正的问题之前,我只想说我可能会在这里得到一些错误的细节.如果是这样,请逮捕我,甚至不要回答我的问题.
我的问题基本上是关于DLL和.NET的.我们有一个使用相当多内存的应用程序,我们正试图弄清楚如何正确地测量它,特别是当问题主要发生在客户端的计算机上时.
让我感到震惊的是,我们有一些相当大的.NET程序集和生成的ORM代码.
如果我使用的是具有唯一基址的非托管(Win32)DLL,则同一台计算机上的多个并发进程会将DLL加载到物理内存中,并将其映射到所有应用程序的虚拟内存中.因此,物理内存将用于此DLL一次.
问题是.NET程序集会发生什么.这个DLL包含IL,虽然它的这一部分可能在应用程序之间共享,但是这个IL产生的JITted代码呢?这是共享的吗?如果没有,我如何衡量以解决这个问题实际上是否导致问题?(是的,我知道,它会有所贡献,但我不会花太多时间在这上面,直到这是最大的问题).
另外,我知道我们没有查看解决方案中所有.NET程序集的基址,.NET程序集是否有必要这样做?如果是这样,是否有一些关于如何确定这些地址的指南?
任何对这一领域的见解都是最受欢迎的,即使事实证明这不是一个大问题,甚至根本不是问题.
编辑:刚刚发现这个问题:.NET程序集和DLL rebasing部分回答了我的问题,但我仍然想知道JITted代码如何影响所有这些.
从该问题及其接受的答案看来,JITted代码放在堆上,这意味着每个进程将加载共享二进制程序集映像,并在其自己的内存空间内生成代码的私有JITted副本.
我们有什么方法可以衡量这一点吗?如果这会产生大量代码,我们必须更多地查看生成的代码,以确定是否需要调整它.
编辑:在此处添加了一个较短的问题列表:
@Brian Rasmussen 在这里的答案表明JITting将按照我的预期生成JITted代码的每个进程副本,但是重新组装程序集实际上会减少内存使用量.我将不得不深入研究他提到的WinDbg + SoS工具,我已经在我的列表上停留了一段时间,但现在我怀疑我不能再把它关掉了:)
编辑:我在这个主题上找到的一些链接:
正如问题所说,我想从内存中的位置而不是文件加载DLL,类似于LoadLibrary(Ex).我不是WinAPI的专家,所以google了一下,发现这篇文章与MemoryModule库一起完全满足我的需求.
另一方面,信息很旧,图书馆也没有更新一段时间.所以我想知道是否有不同的,更新的和更好的方法来做到这一点.此外,如果有人使用了文章中提到的库,他们是否可以提供有关使用它时可能遇到的问题的见解?
对于好奇的,我正在探索加密应用程序的一些插件的概念,而不将解密的版本存储在磁盘上.
我正在构建一个DLL类库 - 我希望尽可能多的人使用它.我应该使用哪个版本的.NET Framework和哪个C#版本?是否可以为不同版本生成向后兼容的DLL或不同的DLL?或者Windows是否自动更新.NET框架,所以我应该使用最新版本?任何指导赞赏!
在C++中开发一个返回boost共享指针并将它们用作参数的DLL是否有效?
那么,导出这样的函数是否可以?
1.) boost::shared_ptr<Connection> startConnection();
2.) void sendToConnection(boost::shared_ptr<Connection> conn, byte* data, int len);
Run Code Online (Sandbox Code Playgroud)
特别说明:引用计数是跨越DLL边界还是需要exe和dll使用相同的运行时?
目的是克服对象所有权的问题.所以当dll和exe都不再引用它时,对象会被删除.
我正在构建一个DLL,我们称之为mydll.dll,在其中我有时需要从webservice,myservice调用方法.mydll.dll是使用C#和.NET 3.5构建的.
为了消耗为MyService从MYDLL我添加了一个服务在Visual Studio 2008中,这或多或少与使用svcutil.exe的.这样做会创建一个我可以创建的类,并将端点和绑定配置添加到mydll app.config.
这里的问题是从未加载mydll app.config.相反,加载的是我使用mydll的程序的app.config或web.config .
我希望mydll能够进化,这就是为什么我将它的功能从我的系统的其他部分开始解耦.在这个演变过程中,它可能会增加更多的Web服务,它会调用手动复制粘贴方法来克服这个问题.
我已经研究了几种可能的攻击方法:
我不知道该走哪条路.选项3听起来很有希望,但事实证明这是很多工作,可能会引入一些错误,所以它无疑是值得的.我也不熟悉规范svcutil.exe以外的任何工具.
请为上述替代方案提供优缺点,提供实施其中任何方案的提示,或建议其他方法.
谢谢,
阿萨夫
我有一个问题要问你.
我有一个C++源代码和一个头文件.C++文件使用windows.h库,使用串口进行操作(基本操作:read(),write()等).
我想要做的是,使用这些文件创建一个库,并在我的C#.Net解决方案中使用该库.
我需要创建什么类型的库?我该怎么做?创建库后,如何将其导入C#解决方案?
我最诚挚的问候.
我正在使用的代码部件:
// MathFuncsDll.h
namespace MathFuncs
{
class MyMathFuncs
{
public:
// Returns a + b
static __declspec(dllexport) double Add(double a, double b);
// Returns a - b
static __declspec(dllexport) double Subtract(double a, double b);
// Returns a * b
static __declspec(dllexport) double Multiply(double a, double b);
// Returns a / b
// Throws DivideByZeroException if b is 0
static __declspec(dllexport) double Divide(double a, double b);
};
}
// MathFuncsDll.cpp
// compile …
Run Code Online (Sandbox Code Playgroud) 好的,所以我已经阅读了几个关于这个主题的问题和文章,我觉得我理解基础知识,但我仍然遇到麻烦.
我有一个DLL导出一个具有std :: string作为成员的类.我的主程序包含也有字符串的类,它使用DLL.
如果我在VS2010中编译DLL,我会收到以下警告:
warning C4251: 'MyClass::data' : class 'std::basic_string<_Elem,_Traits,_Ax>' needs to have dll-interface to be used by clients of class 'MyClass'
Run Code Online (Sandbox Code Playgroud)
当我编译EXE时,我得到相同的警告,但没有错误,程序编译并运行.实际上,这是一个大项目,所以我得到了40个警告,我不太热衷于此.(作为侧面观察,使用VS2008编译时不会出现这些警告)
所以,我读到了这个警告,它引导我阅读这篇MS文章:http: //support.microsoft.com/default.aspx? scid = KB; EN-US; 168958,它告诉我如何从一个STL模板导出DLL来满足我得到的警告.
问题是,当我添加以下行以删除警告时:
EXPIMP_TEMPLATE template class DECLSPECIFIER std::allocator<char>;
EXPIMP_TEMPLATE template class DECLSPECIFIER std::basic_string< char, std::char_traits<char>, std::allocator<char> >;
Run Code Online (Sandbox Code Playgroud)
DLL编译没有警告,但是当我编译我的EXE时,链接器会抛出一个拟合:
2>SampleDLL.lib(SampleDLL.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in OtherClass.obj
2>SampleDLL.lib(SampleDLL.dll) : error LNK2005: "public: unsigned int __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::size(void)const " …
Run Code Online (Sandbox Code Playgroud) 首先 - 如果已经回答了一百次,我很抱歉!D'哦!
但我的搜索显然很糟糕,因为我没有运气回答这个基本问题:
资源如何存储在EXE/DLL中?作为UNICODE(UCS-2,Windows本机内部字符格式),还是使用资源块代码页的多字节字符?
我只是寻找一般答案或链接到详细信息,而不是将UNICODE字符串放入.rc字符串表的详细方法.谢谢!
在我工作的地方,我们刚刚发布了一个使用dll的功能,该功能严重依赖于接口.dll和所有客户端应用程序都是用Delphi编写的.无需注册.这个DLL不是一个合适的com服务器.唯一的限制是dll和客户端应用程序都可以访问包含接口的单元.这允许我们将复杂数据传递给使用此dll的应用程序,而不需要求助于记录指针,数组或极其繁重的函数签名,也不需要bpl或完全兼容的COM服务器引入的包袱.
看起来它解决了我们遇到的一个没有缺点的重大问题.不幸的是有一个缺点.接口发布后对接口的任何更改都需要随后重新编译该接口的任何使用者.这对于属于同一发布周期的项目来说很好,但是我们的一些项目有不同的发布计划.
我对此进行了一些研究,看起来通常的做法是引入一个继承自之前发布的接口的新接口,而不是修改原始接口.
type
IOriginalInterface = interface
['{8B598EC1-AD92-4144-A1BE-9062C5EA0748}']
procedure DoSomething;
end;
INewInterface = interface(IOriginalInterface)
['{DD9D9DE0-0F87-4BC5-803C-74C8AB0F3E39}']
procedure DoSomethingElse;
end;
Run Code Online (Sandbox Code Playgroud)
这可确保针对原始接口编译的旧可执行文件继续有效.
我注意到使用RAD Studio打开工具api时,只要引入了新的接口,就会重命名接口.因此,不是为最新的界面提供新名称,而是最新的界面获取原始界面的名称,并重命名原始界面.
type
IOldInterface = interface
['{8B598EC1-AD92-4144-A1BE-9062C5EA0748}']
procedure DoSomething;
end;
IOriginalInterface = interface(IOldInterface)
['{DD9D9DE0-0F87-4BC5-803C-74C8AB0F3E39}']
procedure DoSomethingElse;
end;
Run Code Online (Sandbox Code Playgroud)
这显然适用于RAD Studio团队以及第三方扩展供应商.这可确保任何重新编译的客户端都将使用最新的接口,而无需更改任何代码.我认为这是有效的,因为名称是无关紧要的,并且在编译代码之后剩下的只是接口定义,使用GUID解析.
说了这么多,这是我们现在面临的界面版本问题的一个很好的解决方案吗?还有其他问题需要注意吗?
dll ×10
c++ ×5
.net ×3
c# ×2
winapi ×2
app-config ×1
base-address ×1
boost ×1
build ×1
c ×1
com ×1
delphi ×1
interface ×1
memory ×1
rc ×1
resources ×1
serial-port ×1
shared-ptr ×1
stl ×1
svcutil.exe ×1
version ×1
web-services ×1