Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从非STA线程和/或64位进程使用C#中的32位COM库 我试图在C++应用程序中使用一个遗留的COM组件(可能是C++中创建的DLL库,32位)。我需要让它在以下情况下工作: x86 STA线程中使用的COM组件(例如主应用程序线程) x86工作线程中使用的COM组件(例如任务/线程池) x64 STA线程中使用的COM组件(例如主应用程序线程) x64工作线程中使用的COM组件(例如任务/线程池)_C#_Dll_Com_Interop_Regsvr32 - Fatal编程技术网

如何从非STA线程和/或64位进程使用C#中的32位COM库 我试图在C++应用程序中使用一个遗留的COM组件(可能是C++中创建的DLL库,32位)。我需要让它在以下情况下工作: x86 STA线程中使用的COM组件(例如主应用程序线程) x86工作线程中使用的COM组件(例如任务/线程池) x64 STA线程中使用的COM组件(例如主应用程序线程) x64工作线程中使用的COM组件(例如任务/线程池)

如何从非STA线程和/或64位进程使用C#中的32位COM库 我试图在C++应用程序中使用一个遗留的COM组件(可能是C++中创建的DLL库,32位)。我需要让它在以下情况下工作: x86 STA线程中使用的COM组件(例如主应用程序线程) x86工作线程中使用的COM组件(例如任务/线程池) x64 STA线程中使用的COM组件(例如主应用程序线程) x64工作线程中使用的COM组件(例如任务/线程池),c#,dll,com,interop,regsvr32,C#,Dll,Com,Interop,Regsvr32,到目前为止,我已经在场景1中使用了它。我还为场景2创建了PoC包装器——但这不是我现在想要遵循的方式。总而言之,只有场景1可以正常工作。其余的根本没有 我做了一些研究,发现情景1应该相当简单。的确如此。我还了解到,当COM组件托管在代理(32位?)进程中时,场景2、3、4也应该是可能的。在这种情况下,可能会出现严重的性能损失,但我现在不太关心性能 虽然我试了很多次,但都没能成功。我已经没有主意了,需要你的帮助。 让我先描述一下我的设置。开头提到的COM组件作为以下一组文件提供: GeoDefs

到目前为止,我已经在场景1中使用了它。我还为场景2创建了PoC包装器——但这不是我现在想要遵循的方式。总而言之,只有场景1可以正常工作。其余的根本没有

我做了一些研究,发现情景1应该相当简单。的确如此。我还了解到,当COM组件托管在代理(32位?)进程中时,场景2、3、4也应该是可能的。在这种情况下,可能会出现严重的性能损失,但我现在不太关心性能

虽然我试了很多次,但都没能成功。我已经没有主意了,需要你的帮助。 让我先描述一下我的设置。开头提到的COM组件作为以下一组文件提供:

  • GeoDefs.dll
  • GeoDefs.tlb
  • GeomDefs.dll
  • GeomDefs.tlb
  • GeoFunc.dll
  • GeoFunc.tlb
  • GeomFunc.dll
  • GeomFunc.tlb
  • GeoDatumKrtgrf.dll
  • GeoDatumKrtgrf.tlb
我已使用regsvr32工具注册了上述所有(5)个dll文件。注册成功。我创建了简单的C#WinForms应用程序,并将COM引用添加到我的项目中:

  • GeoDatumKrtgrf 1.0类型库
  • GeoDefs 1.0类型库
  • GeoFunc 1.0类型库
  • GeomDefs 1.0类型库
  • GeomFunc 1.0类型库
Visual Studio已创建互操作程序集(放置在obj文件夹中):

  • Interop.GEODATUMKRTGRFLib.dll
  • Interop.GEODEFSLib.dll
  • Interop.GEOFUNCLib.dll
  • Interop.geomeDefslib.dll
  • Interop.GEOMFUNCLib.dll
参考资料部分中的内容如下:

  • 地理坐标KRTGRFLB
  • 大地裂缝
  • 地理功能库
  • 土工格栅
  • 几何函数库
所有上述引用在属性中将嵌入互操作类型设置为“False”,并将复制本地设置为“True”

最后,我使用两个简单的代码片段来测试COM是否可以正确访问

void btnComInMainThread_Click(object sender, EventArgs e)
{
    try
    {
        var comObject = new GeoDatumKrtgrfClass();

        comObject.InitDatum(eT_DatumTypes.DT_WGS_1984);

        comObject.LG2G(out var lonDouble, out var latDouble, 17000000, 25000000);

        Debug.Assert(Math.Abs(lonDouble - 17.0) < 1e-6 && Math.Abs(latDouble - 25.0) < 1e-6);

        Debug.Print($"{DateTime.Now:HH:mm:ss.fff}: Ok.");
    }
    catch (Exception ex)
    {
        Debug.Print(ex.ToString());
    }
}

void btnComInWorkerThread_Click(object sender, EventArgs e)
{
    Task.Run(() =>
    {
        try
        {
            var comObject = new GeoDatumKrtgrfClass();

            comObject.InitDatum(eT_DatumTypes.DT_WGS_1984);

            comObject.LG2G(out var lonDouble, out var latDouble, 17000000, 25000000);

            Debug.Assert(Math.Abs(lonDouble - 17.0) < 1e-6 && Math.Abs(latDouble - 25.0) < 1e-6);

            Debug.Print($"{DateTime.Now:HH:mm:ss.fff}: Ok.");
        }
        catch (Exception ex)
        {
            Debug.Print(ex.ToString());
        }
   });
}
下面我将包括一些来自OLE/COM对象查看器和ILSpy的(缩短的)额外信息

GeoDatumKrtgrf.tlb

// Generated .IDL file (by the OLE/COM Object Viewer)
// 
// typelib filename: GeoDatumKrtgrf.tlb

[
  uuid(D541177E-570B-4F7F-A6B0-931C0BAC85C9),
  version(1.0),
  helpstring("GeoDatumKrtgrf 1.0 Type Library"),
  custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 100663662),
  custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1302262921),
  custom(DE77BA65-517C-11D1-A2DA-0000F8773CE9, "Created by MIDL version 6.00.0366 at Fri Apr 08 13:41:58 2011
")

]
library GEODATUMKRTGRFLib
{
    // TLib :     // TLib : GeoDefs 1.0 Type Library : {3EB9DBAA-44B4-4FFE-AAA2-FA7AFC6FC228}
    importlib("GeoDefs.tlb");
    // TLib : GeomDefs 1.0 Type Library : {F28B71EA-132F-4C47-AAB1-1218716945E5}
    importlib("GeomDefs.tlb");

    // Forward declare all types defined in this typelib
    interface IGeoDatumKrtgrf;

    [
      uuid(7948C0A1-0806-406A-B5A1-34A9106B8C37),
      helpstring("GeoDatumKrtgrf Class")
    ]
    coclass GeoDatumKrtgrf {
    [default] interface IGeoDatumKrtgrf;
    };

    [
      odl,
      uuid(C6ACFB21-24DC-43FB-AF7F-07EB526D2DF5),
      helpstring("IGeoDatumKrtgrf Interface")
    ]
    interface IGeoDatumKrtgrf : IGeoDatum {

    ...

    [helpstring("method LG2G")]
    HRESULT _stdcall LG2G(
            [out] double* pd_Lon, 
            [out] double* pd_Lat, 
            [in] long l_Lon, 
            [in] long l_Lat);

    ...

    };
};
GeoDefs.tlb

// Generated .IDL file (by the OLE/COM Object Viewer)
// 
// typelib filename: GeoDefs.tlb

[
  uuid(3EB9DBAA-44B4-4FFE-AAA2-FA7AFC6FC228),
  version(1.0),
  helpstring("GeoDefs 1.0 Type Library"),
  custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 100663662),
  custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1302262808),
  custom(DE77BA65-517C-11D1-A2DA-0000F8773CE9, "Created by MIDL version 6.00.0366 at Fri Apr 08 13:40:05 2011
")

]
library GEODEFSLib
{
    // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("stdole2.tlb");

    ...

    [
      odl,
      uuid(69E77C75-BB8D-46F9-BD93-1D26E09249DE),
      helpstring("IGeoDatum Interface")
    ]
    interface IGeoDatum : IUnknown {
    HRESULT _stdcall InitDatum([in] eT_DatumTypes e_Datum);
    HRESULT _stdcall SetViewByR(
            [in] stT_GeoRect* pst_GeoRect, 
            [in, out] tagRECT* pst_Rect);
    HRESULT _stdcall SetViewByP(
            [in] stT_GeoCoord* pst_GeoCoordLB, 
            [in] stT_GeoCoord* pst_GeoCoordRT, 
            [in, out] tagPOINT* pst_PntLB, 
            [in, out] tagPOINT* pst_PntRT);
    HRESULT _stdcall G2L(
            [in] double d_Lon, 
            [in] double d_Lat, 
            [in, out] long* pl_X, 
            [in, out] long* pl_Y);
    HRESULT _stdcall L2G(
            [in] long l_X, 
            [in] long l_Y, 
            [in, out] double* pd_Lon, 
            [in, out] double* pd_Lat);
    HRESULT _stdcall GP2LP(
            [in] stT_GeoCoord* pst_GeoCoord, 
            [in, out] tagPOINT* pst_Pnt);
    HRESULT _stdcall LP2GP(
            [in] tagPOINT* pst_Pnt, 
            [in, out] stT_GeoCoord* pst_GeoCoord);
    HRESULT _stdcall GR2LR(
            [in] stT_GeoRect* pst_GeoRect, 
            [in, out] tagRECT* pst_Rect);
    HRESULT _stdcall LR2GR(
            [in] tagRECT* pst_Rect, 
            [in, out] stT_GeoRect* pst_GeoRect);
    [helpstring("method NormalizeGR")]
    HRESULT _stdcall NormalizeGR([in, out] stT_GeoRect* pst_GeoRect);
    };

    ...

    [
      uuid(38EE7367-30EC-43A7-96F6-C55BC39B62C0),
      helpstring("Cnv Class")
    ]
    coclass Cnv {
    [default] interface ICnv;
    };

    [
      odl,
      uuid(6C92FACA-266F-4943-B4AE-7E538F6FC672),
      helpstring("ICnv Interface")
    ]
    interface ICnv : IUnknown {
    [helpstring("method dms2dd")]
    HRESULT _stdcall dms2dd(
            [in] stT_GeoCoordDMS* pst_GeoCoordDMS, 
            [out, retval] stT_GeoCoord* pst_GeoCoord);
    [helpstring("method dd2dms")]
    HRESULT _stdcall dd2dms(
            [in] stT_GeoCoord* pst_GeoCoord, 
            [out, retval] stT_GeoCoordDMS* pst_GeoCoordDMS);
    [helpstring("method dm2dd")]
    HRESULT _stdcall dm2dd(
            [in] stT_GeoCoordDM* pst_GeoCoordDM, 
            [out, retval] stT_GeoCoord* pst_GeoCoord);
    [helpstring("method dd2dm")]
    HRESULT _stdcall dd2dm(
            [in] stT_GeoCoord* pst_GeoCoord, 
            [out, retval] stT_GeoCoordDM* pst_GeoCoordDM);
    [helpstring("method DDMMSS2d")]
    HRESULT _stdcall DDMMSS2d(
            [out] stT_GeoCoord* pst_GeoCoord, 
            [in] long l_Lon, 
            [in] long l_Lat);
    [helpstring("method d2DDMMSS")]
    HRESULT _stdcall d2DDMMSS(
            [out] long* pl_Lon, 
            [out] long* pl_Lat, 
            [in] stT_GeoCoord* pst_GeoCoord);
    [helpstring("method dmsTodd")]
    HRESULT _stdcall dmsTodd(
            [in] stT_GeoCoordDMS* pst_GeoCoordDMS, 
            [out] stT_GeoCoord* pst_GeoCoord);
    [helpstring("method ddTodms")]
    HRESULT _stdcall ddTodms(
            [in] stT_GeoCoord* pst_GeoCoord, 
            [out] stT_GeoCoordDMS* pst_GeoCoordDMS);
    [helpstring("method dmshToddh")]
    HRESULT _stdcall dmshToddh(
            [in] stT_GeoCoordDMSH* pst_GeoCoordDMSH, 
            [out] stT_GeoCoordH* pst_GeoCoordH);
    [helpstring("method ddhTodmsh")]
    HRESULT _stdcall ddhTodmsh(
            [in] stT_GeoCoordH* pst_GeoCoordH, 
            [out] stT_GeoCoordDMSH* pst_GeoCoordDMSH);
    [helpstring("method dd2ch")]
    HRESULT _stdcall dd2ch(
            [in] stT_GeoCoord* pst_GeoCoord, 
            [out] BSTR* pac_Lat, 
            [out] BSTR* pac_Lon);
    };
};
Interop.GEODATUMKRTGRFLib.dll 1/3

// GEODATUMKRTGRFLib.GeoDatumKrtgrfClass
using GEODATUMKRTGRFLib;
using GEODEFSLib;
using GEOMDEFSLib;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[ComImport]
[ClassInterface(0)]
[TypeLibType(2)]
[Guid("7948C0A1-0806-406A-B5A1-34A9106B8C37")]
public class GeoDatumKrtgrfClass : IGeoDatumKrtgrf, GeoDatumKrtgrf
{
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern GeoDatumKrtgrfClass();

    [MethodImpl(MethodImplOptions.InternalCall)]
    public virtual extern void InitDatum([In] eT_DatumTypes e_Datum);

    void IGeoDatumKrtgrf.InitDatum([In] eT_DatumTypes e_Datum)
    {
        //ILSpy generated this explicit interface implementation from .override directive in InitDatum
        this.InitDatum(e_Datum);
    }

    ...

    [MethodImpl(MethodImplOptions.InternalCall)]
    public virtual extern void LG2G(out double pd_Lon, out double pd_Lat, [In] int l_Lon, [In] int l_Lat);

    void IGeoDatumKrtgrf.LG2G(out double pd_Lon, out double pd_Lat, [In] int l_Lon, [In] int l_Lat)
    {
        //ILSpy generated this explicit interface implementation from .override directive in LG2G
        this.LG2G(out pd_Lon, out pd_Lat, l_Lon, l_Lat);
    }

    ...

}
Interop.GEODATUMKRTGRFLib.dll 2/3

// GEODATUMKRTGRFLib.IGeoDatumKrtgrf
using GEODEFSLib;
using GEOMDEFSLib;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[ComImport]
[Guid("C6ACFB21-24DC-43FB-AF7F-07EB526D2DF5")]
[InterfaceType(1)]
public interface IGeoDatumKrtgrf : IGeoDatum
{
    [MethodImpl(MethodImplOptions.InternalCall)]
    new void InitDatum([In] eT_DatumTypes e_Datum);

    ...

    [MethodImpl(MethodImplOptions.InternalCall)]
    void LG2G(out double pd_Lon, out double pd_Lat, [In] int l_Lon, [In] int l_Lat);

    ...

}
Interop.GEODATUMKRTGRFLib.dll 3/3

// GEODATUMKRTGRFLib.GeoDatumKrtgrf
using GEODATUMKRTGRFLib;
using System.Runtime.InteropServices;

[ComImport]
[Guid("C6ACFB21-24DC-43FB-AF7F-07EB526D2DF5")]
[CoClass(typeof(GeoDatumKrtgrfClass))]
public interface GeoDatumKrtgrf : IGeoDatumKrtgrf
{
}
Interop.GEODEFSLib.dll

// GEODEFSLib.IGeoDatum
using GEODEFSLib;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[ComImport]
[Guid("69E77C75-BB8D-46F9-BD93-1D26E09249DE")]
[InterfaceType(1)]
public interface IGeoDatum
{
    [MethodImpl(MethodImplOptions.InternalCall)]
    void InitDatum([In] eT_DatumTypes e_Datum);

    ...
}
还有Cnv、CnvClass和ICnv(以及许多结构和枚举),它们似乎不太相关,目前不包括在内

说到以上,我想补充一点,我还试图手动调整系统注册表。它相当混乱,没有带来任何改善


我希望您能帮助我运行所有四种方案。

不,这是行不通的。周围有很多地理库,是时候让这一个满足它的制造商了。@HansPassant为了简单起见,我把重点放在了地理计算上。我同意,典型的地质计算方法很容易替换。但是,在某些地方,这些库中只包含简单的计算(例如,某些方法生成固定大小的小型位图图形)。更重要的是,我们并不总是知道用于产生结果的算法。如果有机会找到一个解决方案并使其全部运行,那就太好了。
// GEODEFSLib.IGeoDatum
using GEODEFSLib;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[ComImport]
[Guid("69E77C75-BB8D-46F9-BD93-1D26E09249DE")]
[InterfaceType(1)]
public interface IGeoDatum
{
    [MethodImpl(MethodImplOptions.InternalCall)]
    void InitDatum([In] eT_DatumTypes e_Datum);

    ...
}