我有一个托管对象调用COM服务器来分配一些内存.在托管对象消失之前,托管对象必须再次调用COM服务器以释放该内存,以避免内存泄漏.此对象实现IDisposable以帮助确保正确释放内存的COM调用.
如果没有调用该Dispose方法,我希望对象的终结器释放内存.问题是,最终确定的规则是你不能访问任何引用,因为你不知道在你之前已经GC和/或最终确定了哪些其他对象.这使得唯一可触摸的对象状态为字段(句柄是最常见的).
但是调用COM服务器涉及通过运行时可调用包装器(RCW)来释放我有一个存储在字段中的cookie的内存. 从终结器调用RCW是否安全(是否保证此时没有GC或最终确定)?
对于那些不熟悉终结的人来说,虽然终结器线程在托管应用程序域运行的同时在托管应用程序域的后台运行,但是对于那些触摸引用的情况理论上可以正常,最终化也会在appdomain shutdown和任何顺序中发生 - 不是只是在参考关系顺序.这限制了您可以认为从终结器触摸的安全性.即使引用为非null,对托管对象的任何引用都可能是"坏"(收集的内存).
更新:我刚试了一下,得到了这个:
myassembly.dll中发生未处理的"System.Runtime.InteropServices.InvalidComObjectException"类型异常
附加信息:无法使用已与其基础RCW分离的COM对象.
对于其中一个副项目,我需要编写一个需要使用第三方INPROC COM对象的C#应用程序.不幸的是,C#不是我的主要编程语言,所以我的知识有点受限.有关如何从C#访问COM对象的任何好的教程吗?使用此第三方COM对象需要我创建指定COM接口的实现,并将该实现提供给COM对象以使其起作用.
组件对象模型(COM)是(或者是......)Windows中提供与语言无关的软件组件的方式.
Linux/UNIX中是否有任何编程模型与二进制组件的代码重用原理相同?
让我们说我正在访问第三方库,其文档声明我可以使用pInvoke或创建互操作库并使用COM.这两种技术有什么区别,为什么我可以选择其中一种?
其中一些预处理器定义位于WinMain函数和其他Windows库函数中.他们的目的是什么?他们是如何工作的?将它们写入您的实现或函数调用是一种好习惯吗?
我最初的研究表明,他们只是设置为:
#define __in
#define __out
#define __in_opt
Run Code Online (Sandbox Code Playgroud)
意味着它们在预处理器传递中没有被替换.它们只是一种文档方法,没有任何功能吗?
如果是这样,我可以看到像这样记录代码的优势.像doxygen这样的东西你需要写出两次参数名称.因此,理论上这有助于减少重复,并保持一致性......
我没有关于如何__allowed()运作的理论.
我在这里有点头脑,想要了解如何去做.
基本上我想要做的是能够在我的C++应用程序中呈现和控制silverlight.我想要的东西是:
class silverlight_host
{
public:
// Prio 1
silverlight_host(const std::string& filename); // Load a xap file
void draw(void* dest); // Draw with alpha to dest
std::pair<size_t, size_t> get_size(); // Need to know required size of dest
// Prio 2
bool is_dirty() const; // Check for dirty rect since last call to draw
void send_param(const std::string& param); // Send data to silverlight control or call functions. Alternative name maybe, call_function
void set_size(size_t width, size_t height); // Set the size of …Run Code Online (Sandbox Code Playgroud) 是否可以使用NuGet来分发COM DLL?
我该如何设置包装?
我想我可以将DLL放在Tools目录中,然后运行安装后脚本来注册库,但我不是很擅长PowerShell.
是否有任何在线示例如何执行此操作(如果可能)?
如何通过在C#中反映COM对象来读出所有属性名称?如果我知道名字,我知道如何获得财产.
comObject.GetType().InvokeMember("PropertyName", System.Reflection.BindingFlags.GetProperty, null, comObject, null);
Run Code Online (Sandbox Code Playgroud)
但什么时候我想转储所有属性?
PropertyInfo[] properties = t.GetProperties();
Run Code Online (Sandbox Code Playgroud)
这种方式不适用于Com-Objects.如果我做一个GetMembers()我得到这些成员:
Name: GetLifetimeService
Name: InitializeLifetimeService
Name: CreateObjRef
Name: ToString
Name: Equals
Name: GetHashCode
Name: GetType
Run Code Online (Sandbox Code Playgroud)
对克里斯说
当一个COM对象在STA线程上实例化时,该线程通常必须实现一个消息泵,以便为来回调用其他线程(见这里).
可以手动泵送消息,或者依赖于某些(但不是全部)线程阻塞操作在等待时自动泵送COM相关消息的事实.文档通常无助于决定哪个是哪个(参见相关问题).
如何确定线程阻塞操作是否会在STA上泵送COM消息?
到目前为止的部分清单:
阻断其业务做泵*:
Thread.JoinWaitHandle.WaitOne/ WaitAny/WaitAll(WaitAll不能从一个STA线程虽然称为)GC.WaitForPendingFinalizersMonitor.Enter(因此lock) - 在某些条件下ReaderWriterLock阻止不泵送的操作:
Thread.SleepConsole.ReadKey (在某处读)*注意Noseratio的答案说,即使是操作泵,也是为非常有限的未公开的COM特定消息集.
我有一个由C#编写的DLL文件,我的系统是Windows 7 64位.当我应用RegAsm时,它没有将注册表添加到64位路径,而只是将其添加到32位路径.
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" /register /codebase "C:\o.dll"
Run Code Online (Sandbox Code Playgroud)
然后,如果我在regedit.exe中检查我的GUID,我看到我只在32位注册表路径中有它: HKEY_CLASSES_ROOT\CLSID\{... my guid is found here ....}
代替 HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{... not found my guid ...}
因此,我有其他问题.任何人都可以建议发生了什么以及为什么它没有制作32位和64位注册表项?"
com ×10
c# ×4
.net ×2
c++ ×2
atl ×1
c ×1
components ×1
finalizer ×1
interop ×1
linux ×1
message-pump ×1
nuget ×1
pinvoke ×1
properties ×1
reflection ×1
regasm ×1
regedit ×1
silverlight ×1
unix ×1
windows ×1
winmain ×1