我认为委托实例可以与函数实例互换.
请使用以下代码:
delegate int AddDelegate(int a, int b);
AddDelegate DelegateInstance;
public void DoStuff()
{
//I can call this without a delegate "instance":
MethodThatTakesAdd(Add);
//I can also call it WITH a delegate "instance"
DelegateInstance = Add;
MethodThatTakesAdd(DelegateInstance);
}
public int Add(int a, int b)
{
return a + b;
}
public void MethodThatTakesAdd(AddDelegate addFunction)
{
Console.WriteLine(addFunction(1, 2).ToString());
}
Run Code Online (Sandbox Code Playgroud)
两种方式称它为APPEAR是等价的,如果你只使用C#,你将永远不会看到差异(至少我还没有达到这一点).但是,我最近是一个回调到这个托管代码的非托管代码,它们的处理方式不同.例如,在一个场景中,如果我直接将函数用作回调(即使我的对象实例被保留),我也会得到错误"对垃圾收集的委托进行了回调".使用"委托实例"可以解决问题.
那里有人知道有什么区别吗?
正确构建托管代码Visual Studio(并递归地)将引用的托管项目的dll复制到正在构建的项目的输出文件夹中.
但是,如果其中一个引用是依赖于非托管dll的托管DLL,则这些非托管DLL不会复制到输出文件夹,即使它们在相同解决方案中的相应项目并列为托管DLL的依赖项.
我意识到可以通过让所有项目使用相同的输出文件夹来解决此问题.我们已经为大多数项目执行了此操作,但我们更喜欢将单元测试输出文件夹分开,导致上述问题用于使用具有非托管依赖项的托管Dll的单元测试.
我们现在使用的解决方案是复制必要的DLL的预构建事件,但这会浪费时间并且容易出错,因为需要为使用托管DLL的每个项目重复这些事件.
因此,我想知道是否有一种方法可以让构建系统理解它应该总是在它决定复制托管DLL时复制托管DLL的非托管依赖项?
我目前正在为非托管dll创建托管包装器.Point是包装器对非托管dll进行TON调用,但本身只输出很少的方法.从我做的研究中,这应该是安全的,但我想确保我得到正确的.基本上这就是我在做的方式.
[SuppressUnmanagedCodeSecurity()]
internal static class SomeAPI
{
[DllImport("base.dll"]
internal static extern bool Somefunc();
[...] Other internal DllImports
}
public class Wrapper : IDisposable
{
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
public Wrapper()
{
SomeAPI.SomeFunc();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
protected override void Dispose(bool disposeManagedResources)
{
SomeAPI.SomeFunc();
}
}
Run Code Online (Sandbox Code Playgroud)
我添加的每个受保护或公共的方法都应该获得[SecurityPermission(SecurityAction.Demand,UnmanagedCode = true)]属性.我的意思是每一个都避免意外的代码路径导致SomeAPI调用.
现在添加到内部或私有的Wrapper的任何方法都是"安全的".这个假设是否正确?
对不起,如果我不清楚.我正在编写包装器,因此它不会重新格式化硬盘驱动器或类似的东西.包装器将在其自己的托管dll中显示(以及其他内容).因为对包装器的一次调用可能导致对非托管dll的100次调用,所以我不希望CLR的性能开销检查所有这些调用 - 因此使用SuppressUnmanagedCodeSecurity.文档提到"非常谨慎地使用此属性.不正确的使用可能会产生安全漏洞.",这就是我要问的问题,使用上述方法再次"安全".
我的Mono应用程序在Mac上崩溃并显示此消息(完整日志):
$ mono --debug bin/Debug/SparkleShare.app/Contents/MonoBundle/SparkleShare.exe
[...]
Stack overflow in unmanaged: IP: 0x26eb76, fault addr: 0xbf808ffc
[...]
Run Code Online (Sandbox Code Playgroud)
"in unmanaged"意味着堆栈溢出不在我的代码中(我只有托管代码),而是在我嵌入的库(SQLite,DotCmis,NewtonSoft.Json)或Mono的代码中.
即使我在调试模式下编译并运行,我得到的只是这两个十六进制.
问题:如何调查此堆栈溢出?任何诡计?
注意:相同的库(具有几乎相同的代码)在Linux和Windows上运行良好.
我有一个用本机C++编写的应用程序,它使用wxWidgets工具包的wxODBC数据库访问库,该库将从wxWidgets的所有未来版本中删除.我需要用另一种支持下面列出的假设和约束的数据库访问方法来替换它.我不要求替换使用本机DBMS API或ODBC,但它必须符合下面列出的限制.
图书馆必须:
不错但可选:
哪些好的库可用 - 免费,开源或付费 - 从单个API(包括Oracle和Microsoft SQL Server)支持多个DBMS,并且可以在本机C++中使用?
请描述您过去的经历 - 好或坏 - 与给定的图书馆以及您为什么要针对特定图书馆提出建议,特别是关于上述假设和约束.
在 Media Foundation SDK 上,我尝试使用 C# 实现GetPhysicalMonitorsFromHMONITOR函数,但没有成功......
在返回的 PHYSICAL_MONITOR[] 中,该函数返回监视器的字符串描述,但由于一些神秘的原因,hPhysicalMonitor句柄保持为 0。
我已经使用 P/Invoke Interop Assistant 生成了签名,并稍作修改。
PHYSICAL_MONITOR 结构或其他任何东西是否需要进一步调整?
谢谢你。
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using WindowsFormsApplication1;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public enum MC_DISPLAY_TECHNOLOGY_TYPE
{
MC_SHADOW_MASK_CATHODE_RAY_TUBE,
MC_APERTURE_GRILL_CATHODE_RAY_TUBE,
MC_THIN_FILM_TRANSISTOR,
MC_LIQUID_CRYSTAL_ON_SILICON,
MC_PLASMA,
MC_ORGANIC_LIGHT_EMITTING_DIODE,
MC_ELECTROLUMINESCENT,
MC_MICROELECTROMECHANICAL,
MC_FIELD_EMISSION_DEVICE,
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PHYSICAL_MONITOR
{
public IntPtr hPhysicalMonitor;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szPhysicalMonitorDescription;
}
#region Imports
[DllImport("user32.dll", EntryPoint = "MonitorFromWindow")] …Run Code Online (Sandbox Code Playgroud) 如标题中所述,我希望我的旧C++库在托管.NET中运行.我想到了两种可能性:
1)我可能尝试使用/ clr编译库并尝试"It Just Works"方法.
2)我可能会将托管包装器写入非托管库.
首先,我想让我的库快速工作,就像在非托管环境中一样.因此,我不确定第一种方法是否会导致性能大幅下降.但是,实现它似乎更快(不是一个正确的词:-))(假设它对我有用).
另一方面,我想到了编写包装器时可能出现的一些问题(例如,如何包装一些STL集合(vector例如)?)我想写一个与非托管C++驻留在同一个项目中的包装器 - 是合理的方法(例如MyUnmanagedClass,MyManagedClass在同一个项目中,第二个包装另一个)?
你会在那个问题上提出什么建议?哪种解决方案能够让我更好地了解生成的代码?
提前感谢您的任何建议和线索!
干杯
当我的类包含套接字和事件时,如何实现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对象?谢谢.
我发现,将出口库管理代码,非托管,所以你可以使用它的非托管像C/C++语言.但我没有找到任何可以解释它是如何完成的(这是我更感兴趣的)
我正在寻找信息,教程,文章,代码源或任何可以帮助我理解其工作原理的东西
另外,如果您在书签中找到了一些钩子/绕道资源,我也很乐意阅读它们:)
在此先感谢您,祝您度过愉快的一天.
我有一个基于 ASP.NET 用 C# 编写的 webapp。它加载(使用LoadLibraryEx)一个用 C++Builder 编写的非托管 DLL。
由于我有性能问题,我做了一些测试和比较,在 DLL 中始终运行相同的方法多次,获得平均时间。
我发现DLL:
如您所见,案例 1 和案例 2 的性能非常相似。
为什么情况 3 这么慢?也许 IIS 会减慢 DLL 的速度?
为此,我使用 JetBrains dotTrace 进行了分析:

是否有任何建议的 IIS 调整?
是否有任何建议的快速替代 IIS 来托管 ASP.NET webapps?
我应该考虑将 webapp 移植到 C++Builder 吗?
编辑:
我尝试将我的 webapp 迁移到 ASP.NET Core(而不是 .NET Framework)并在 Kestrel 上运行它。需要 6.042 秒。因此,与控制台应用程序相比,开销并不大。看来IIS是罪魁祸首......为什么?
unmanaged ×10
c# ×5
managed ×4
.net ×2
c++ ×2
pinvoke ×2
asp.net ×1
database ×1
delegates ×1
dependencies ×1
dispose ×1
dll ×1
export ×1
finalize ×1
hook ×1
iis ×1
interop ×1
intptr ×1
linux ×1
methods ×1
mono ×1
monodevelop ×1
monomac ×1
performance ×1
sockets ×1
structure ×1
windows ×1
wrapper ×1