我是COM的新手,我不知道它是什么或它为什么存在.
这是一种像OOP这样的编程方法吗?编程语言是否必须支持它?(带一些特殊的关键词或其他东西)
当我向我的教授询问时,他说:
COM是一种二进制稳定的OOP方法.我们需要知道二进制布局(某事......某事......)
我不知道这意味着什么.有人说它用于代码重用.OOP在这方面做得很好,那么为什么这个COM首先会发展呢?
它与C++和COM有什么关系?无论我在哪里看到COM,它总是用抽象的C++示例来描述.它只适用于C++吗?
任何人都可以向我展示一个案例或例子,以便我能理解对COM的需求吗?学习这个有什么要求,所以我可以编写自己的组件?
假设我有一个实现IBaseClass的类BaseClass
然后我有一个继承IBaseClass的接口IClass.
然后我有一个名为class的类,它实现了IClass.
例如:
[ComVisible(true), InterfaceType(ComInterfaceType.IsDual), Guid("XXXXXXX")]
public interface IBaseClass
{
[PreserveSig]
string GetA()
}
[ComVisible(true), InterfaceType(ComInterfaceType.IsDual), Guid("XXXXXXX")]
public interface IClass : IBaseClass
{
[PreserveSig]
string GetB()
}
[ComVisible(true), ClassInterface(ClassInterfaceType.None), Guid("XXXXXXX")]
public class BaseClass : IBaseClass
{
public string GetA() { return "A"; }
}
[ComVisible(true), ClassInterface(ClassInterfaceType.None), Guid("XXXXXXX")]
public class Class : BaseClass, IClass
{
public string GetB() { return "B"; }
}
Run Code Online (Sandbox Code Playgroud)
当暴露给COM时,如果我创建一个"Class"实例,它就不允许我调用GetA().
在.tlb文件中查找我的IDL时,我的IClass界面如下所示:
[
odl,
uuid(XXXXXXXXXXXXXXXXXXXXX),
version(1.0),
dual,
oleautomation,
]
interface IClass : IDispatch {
[id(0x60020000)]
BSTR GetB(); …Run Code Online (Sandbox Code Playgroud) 我想设计Delphi插件框架.有三个选项:
1.DLL
2. BPL
3. COM接口
每个选项都有一些缺点.
DLL - 带有MDI apllication的Promblem,来自插件的表单不能嵌入到主机exe-mdi应用程序中.
BPL - 必须使用相同版本的Delphi编译每个*.bpl插件和*.exe主机应用程序.
COM - 接口{xxx-xx-xxx-xx}必须在系统中注册,(regsvr)因此插件框架不能移植!
我上面写的一切都是真的吗?如果没有,请纠正我,还是有其他可能性?
谢谢
我在我的c ++应用程序中嵌入了一个Web浏览器控件.我希望在Web浏览器控件中运行的javascript能够调用c ++函数/方法.
我发现有三种方法可以做到这一点:
我想第三个选项,但我没有找到任何有关如何做到这一点的工作示例.有人可以告诉我该怎么做,或链接到某个网上的工作示例.
最接近我发现的一个例子是Igor Tandetnik在webbrowser_ctl新闻组的一个帖子中的第一个回复.但我担心我需要更多的帮助.
我嵌入了一个IWebBrowser2控件,我没有使用MFC,ATL或WTL.
编辑:
通过Igor在我之前链接的线程中给出的伪代码,以及代码项目文章" 从C++创建JavaScript数组和其他对象 "中找到的代码,我已经生成了一些代码.
void WebForm::AddCustomObject(IDispatch *custObj, std::string name)
{
IHTMLDocument2 *doc = GetDoc();
IHTMLWindow2 *win = NULL;
doc->get_parentWindow(&win);
if (win == NULL) {
return;
}
IDispatchEx *winEx;
win->QueryInterface(&winEx);
if (winEx == NULL) {
return;
}
int lenW = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name.c_str(), -1, NULL, 0);
BSTR objName = SysAllocStringLen(0, lenW);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name.c_str(), -1, objName, lenW);
DISPID dispid;
HRESULT hr = winEx->GetDispID(objName, fdexNameEnsure, …Run Code Online (Sandbox Code Playgroud) 我对用于C++编程的COM智能指针类的选择感到困惑:
我知道有三个四个:
CCOMPtr 来自ATL_com_ptr_t来自MS Com支持类TComInterface (因为我正在使用C++ Builder 2009)CCOMQIPtr,(我之前忘记了)我已经阅读了前两个错误与异常处理差异,但TComInterface似乎完全没有记录.根据我的发现,前两个似乎都有问题或"出乎意料"的行为.
理想情况下,我想要一些干净而现代的C++,但boost::com据我所知不存在......
我需要控制来自其他供应商的应用程序.它们通过TLB文件提供COM接口.
我有以下问题:有没有可能是.NET程序集将regsitered 都与Regasm和Regsvcs?谢谢
我正在尝试将C#与COM Interop库一起使用来打开一组非常繁重的Excel工作簿.我必须使用C#,因为我还需要启动宏,移动一些单元格,并启动我公司使用的自定义excel-add-in.
然后我的程序退出,打开工作簿,每个工作簿都在一个单独的excel实例中.我不希望在程序退出时关闭工作簿.
问题是当我的C#程序退出时,随着时间的推移,excel工作簿逐渐消耗更多的内存,直到他们从原来的500 MB消耗3.5 GB的内存.
我曾经手工打开工作簿,这些工作表从来没有消耗过那么多的记忆.一旦我开始使用C#打开它们,它们就会因极端内存使用而开始破解.我的理论是,不知何故,当我与COM Excel对象交互时,我创建了一个内存泄漏.
以下是我的原始代码:
using Excel = Microsoft.Office.Interop.Excel;
...
excelApp = new Excel.Application();
excelApp.Visible = true;
excelApp.Workbooks.Open(filename, misValue, misValue, misValue, misValue, misValue,
true, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue);
excelApp.Calculation = Excel.XlCalculation.xlCalculationAutomatic;
Run Code Online (Sandbox Code Playgroud)
我读到了你需要如何使用Marshal来释放用途,所以我现在正在尝试以下代码,但没有简单的方法来测试它,除了打开所有工作表并查看它们是否消耗了太多数据.
excelApp = new Excel.Application();
excelApp.Visible = true;
Excel.Workbooks currWorkbooks = excelApp.Workbooks;
Excel.Workbook currWorkbook = currWorkbooks.Open(filename, misValue, misValue, misValue, misValue, misValue,
true, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue);
//excelApp.Calculation = Excel.XlCalculation.xlCalculationAutomatic;
int x = Marshal.ReleaseComObject(currWorkbook);
currWorkbook = null;
int …Run Code Online (Sandbox Code Playgroud) 我想使用await Task.Run(DoWork),在ThreadPool上做一些重复的单线程计算工作.问题是,我需要在里面使用STA COM对象DoWork,所以我想我不能使用ThreadPool因为我不能改变池线程的公寓状态.
我怎样才能在这种情况下使用async/ await?使用自定义任务调度程序创建自己的STA线程池听起来像是一项过度的工作.
默认情况下,.NET对象是自由线程的.如果通过COM封送到另一个线程,它们总是被封送到自己,无论创建者线程是否是STA,并且无论其ThreadingModel注册表值如何.我怀疑,他们聚合了Free Threaded Marshaler(有关COM线程的更多细节可以在这里找到).
我想让我的.NET COM对象在封送到另一个线程时使用标准的COM marshaller代理.问题:
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var apt1 = new WpfApartment();
var apt2 = new WpfApartment();
apt1.Invoke(() =>
{
var comObj = new ComObject();
comObj.Test();
IntPtr pStm;
NativeMethods.CoMarshalInterThreadInterfaceInStream(NativeMethods.IID_IUnknown, comObj, out pStm);
apt2.Invoke(() =>
{
object unk;
NativeMethods.CoGetInterfaceAndReleaseStream(pStm, NativeMethods.IID_IUnknown, out unk);
Console.WriteLine(new { equal = Object.ReferenceEquals(comObj, unk) });
var marshaledComObj = (IComObject)unk;
marshaledComObj.Test();
}); …Run Code Online (Sandbox Code Playgroud) 所以我已经尝试在VBA类实例上调用ITypeInfo,虽然看起来很有希望但我想看看我是否可以获得对其包含项目的引用,类似于类型库.我认为ITypeInfo.GetContainingTypeLib可能很有用,但它会抛出一个异常,表明VBA不会合作.任何人都对VBA如何采用与标准COM规范不同的东西有任何想法?
C#类库代码在这里.注册COM interop并在AssemblyInfo.cs中设置COMVisible(true)以使其可从VBA访问.下面给出的VBA客户端代码.
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace TypeLibraryInspector
{
[ComImport()]
[Guid("00020400-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDispatch
{
[PreserveSig]
int GetTypeInfoCount(out int Count);
[PreserveSig]
int GetTypeInfo
(
[MarshalAs(UnmanagedType.U4)] int iTInfo,
[MarshalAs(UnmanagedType.U4)] int lcid,
out System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo
);
//void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler,
// MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo);
//void GetTypeInfo(int typeInfoIndex, int lcid, out IntPtr piTypeInfo);
[PreserveSig]
int GetIDsOfNames
(
ref Guid riid,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)]
string[] rgsNames,
int cNames,
int lcid,
[MarshalAs(UnmanagedType.LPArray)] int[] rgDispId
); …Run Code Online (Sandbox Code Playgroud) com ×10
.net ×5
c# ×5
c++ ×2
excel ×2
async-await ×1
automation ×1
bpl ×1
c++builder ×1
com+ ×1
com-interop ×1
delphi ×1
dll ×1
inheritance ×1
interface ×1
interop ×1
iwebbrowser2 ×1
javascript ×1
typeinfo ×1
vba ×1
windows ×1