我一直在阅读很多关于C++中非托管DLL的教程/文章.然而,对于我的生活,我似乎无法掌握这个概念.我很容易因为它是否需要头文件,如何导出它,是否需要.lib文件以及你有什么看似不一致而感到困惑.
所以,我们假设我只有这样的函数:
public int calculateSquare(int num)
{
return num*num;
}
Run Code Online (Sandbox Code Playgroud)
忽略实际的代码,我需要做什么才能将这个简单的函数本身变成一个我可以调用的DLL?我只是添加__dllexport或其他任何内容到第一行还是我需要标题?所有这一切让我感到困惑.
我想在我的C#应用程序中嵌入一个命令行实用程序,这样我就可以将其字节作为数组获取并运行可执行文件而无需将其作为单独的文件保存到磁盘(避免将可执行文件存储为单独的文件并避免需要能力在任何地方写临时文件).
我找不到一个只从其字节流运行可执行文件的方法.Windows是否要求它在磁盘上,还是有办法从内存中运行它?如果windows要求它在磁盘上,那么.NET框架中是否有一种简单的方法来创建某种虚拟驱动器/文件并将文件映射到可执行文件的内存流?
我有一个C库.它有许多函数调用,如下所示:
void init_foo( unsigned long x, unsigned long y );
Run Code Online (Sandbox Code Playgroud)
库本身在运行时动态加载(而非插件).标头在所有平台上都是一致的.
我的问题是在Windows和32位linux上,unsigned long是32位,而在64位linux上这是64位.
这个库的各种实现都接受这个,你需要为正确的目标平台构建你的C程序(如预期的那样).
我的互操作方法需要是其中之一,具体取决于架构.
#if lin64
[DllImport("libfoo")]
public static void init_foo( Uint64 x, Uint64 y );
#else
[DllImport("libfoo")]
public static void init_foo( Uint32 x, Uint32 y );
#endif
Run Code Online (Sandbox Code Playgroud)
我可以使用的C#类型在所有平台上都是固定大小的(因为它们应该是).所以我从.Net/Mono传来的托管长期将永远是一个非托管的uint64_t.
我如何处理这个可变整数大小但是有一个程序集可以在.Net或单声道上以32位或64位模式运行?
在.NET中,有几个地方必须保留托管代码并进入非托管又名本机代码领域.仅举几例:
总是有关于从一侧跳到另一侧的开销的评论,我的问题是,如果有人测量了正在发生的确切开销,并且可以解释如何计算它.例如,也许byte[]可以转换为IntPtr甚至可以转换为byte*.NET,并帮助编组程序节省一些CPU周期.
存在许多C++ IDE.但是,我发现Visual Stuido(Visual Studio 2010 Pro)最舒服,因为我花了很多时间.问题是我真的不喜欢.NET依赖产品,无论是速度还是兼容性.
我想没有办法编译没有.NET依赖的VB和C#代码(如果我错了请纠正我).在C++中,有没有办法使用VS IDE及其所有功能,如自动完成,GUI设计等.同时保持所有代码不受管理,以便不需要.NET?
当我的类包含套接字和事件时,如何实现Dispose模式?
它应该是这样的吗?
class MyClass
{
Socket m_ListenerSocket = new Socket();
book m_Disposed=false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool isDisposing)
{
if (!m_Disposed)
{
if (isDisposing)
{
if (m_ListenerSocket != null)
{
m_ListenerSocket.Dispose();
innerClass.Notify -= Notify;
}
}
//finalized unmanged code here
m_Disposed = true;
}
}
~MyClass()
{
Dispose(false);
}
}
Run Code Online (Sandbox Code Playgroud)
我很困惑...套接字类是"托管代码c#版本的winSock"?因此,如果用户名为dispose("isDisposing IS为true"),它应该被释放,那么事件处理程序呢?
所以在最终评论部分应该只释放Inptr对象?谢谢.
当您使用int*C#中的指针时,您需要使用unsafe关键字,但是当您使用关键字时IntPtr,则不需要.这些有什么区别?他们都可以指向一个地址.
垃圾收集器如何处理这两种类型?他们的处理方式不同吗?如果是这样,有什么区别?如果没有,为什么需要unsafe关键字?
编辑:非常感谢大家到目前为止的答案,但我想知道的是框架和垃圾收集器如何处理它们,而不是MSDN的定义IntPtr.只需要一次谷歌搜索即可.我想知道为什么IntPtr不需要unsafe关键字?我想了解为什么我们可以在没有关键字的情况下使用它.
我们在.net项目中引用了第三方专有的CLI DLL.此DLL只是其专有C++库的接口.我们的项目是一个asp.net(MVC4/Web API)Web应用程序.
C++非托管库相当不稳定.有时它会像悬空指针一样崩溃.我们无法解决它,使用此库是一流的客户要求.
当应用程序崩溃时,IIS中的应用程序池不再响应.我们必须重新启动它,这样做需要几分钟(是的,那么久!).
我们希望保持这个不稳定的DLL不会崩溃我们的应用程序.这样做的最佳方式是什么?我们可以将CLI DLL保存在单独的AppDomain中吗?怎么样?
提前致谢.
我想将一段使用Windows Impersonation API的代码包装成一个整洁的小助手类,并且像往常一样,我正在寻找一种先测试的方法.但是,虽然WindowsIdentity是托管类,但实际执行登录所需的LogonUser调用是另一个用户是advapi32.dll中的非托管函数.
我想我可以解决这个问题,为我的助手类引入一个接口,以便在实现中使用和隐藏P/Invoke调用,但测试该实现仍然是个问题.并且你可以想象,实际上在测试中执行模拟可能有点问题,因为用户实际上需要在系统上存在.
unmanaged ×10
.net ×4
c# ×4
c++ ×2
dll ×2
asp.net ×1
dispose ×1
executable ×1
finalize ×1
iis ×1
integer ×1
intptr ×1
memorystream ×1
merge ×1
mono ×1
performance ×1
pointers ×1
sockets ×1
unit-testing ×1