使用PInvoke将句柄传递给托管对象时出现问题 [英] Trouble with passing handle to managed object using PInvoke

查看:123
本文介绍了使用PInvoke将句柄传递给托管对象时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对如何将句柄从.Net传递到非托管代码感到困惑.现在,我正在使用C#开发Oracle Siebel CRM的驱动程序".以及我如何面对如何传递句柄的问题 驱动程序API具有以下方法:

I'm quite confused about how to pass handle to my managed object from .Net to unmanaged code. Now I'm developing kind of "driver" for Oracle Siebel CRM using C#. And how i faced with problem about how to pass handle to Driver API have such method:

ISCAPI ISC_RESULT CreateISCDriverInstance
/* in */(const ISC_STRING mediaTypeStr,
/* in */ const ISC_STRING languageCode,
/* in */ const ISC_STRING connectString,
/* in */ const struct ISC_KVParamList* datasetParams,
/* out */ ISC_DRIVER_HANDLE* handle);

最后一个参数ISC_DRIVER_HANDLE *句柄出现问题.我想说的是,它看起来很奇怪,但是我没有ISC_DRIVER_HANDLE类型的定义.

And i have the problem with last parameter ISC_DRIVER_HANDLE* handle. I want to say that it may looks quite weird, but i don't have a definition of ISC_DRIVER_HANDLE type.

据我所知,可以使用GCHandle对此进行处理...这是我对应如何实现的看法:

As far as I know it's possible to use GCHandle to work with this... And here is my vision about how it should be implemented:

    [STAThread]
[DllExport("CreateISCDriverInstance", CallingConvention = CallingConvention.StdCall)]
public static int CreateIscDriverInstance([MarshalAs(UnmanagedType.LPWStr)] string mediaTypeStr,
    [MarshalAs(UnmanagedType.LPWStr)] string languageCode,
    [MarshalAs(UnmanagedType.LPWStr)] string connectString,
    [In] ref IscKvParamList datasetParams,
    out IntPtr handle)
{
... // Here I'm doing something with incoming data
var drvEntryPointHandle = GCHandle.Alloc(EntryPoints, GCHandleType.Pinned);
handle = GCHandle.ToIntPtr(drvEntryPointHandle);
return (int) ScErrorCode.ScEcOk; 
}

但是,在调用此方法后,我将获得CLR崩溃:(对跟踪数量感到非常抱歉)

But, after call of this method i'll get the CLR crash: (i'm terrible sorry about amount of traces)

ModLoad: C:\Debug\DriverLibrary.dll
ModLoad: C:\Windows\SysWOW64\MSCOREE.DLL
ModLoad: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoreei.dll
ModLoad: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
ModLoad: C:\Windows\SysWOW64\MSVCR120_CLR0400.dll
(730.4a4): Unknown exception - code 04242420 (first chance)
ModLoad: C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\d1265d6159ea876f9d63ea4c1361b587\mscorlib.ni.dll
ModLoad: \DriverLibrary.dll
ModLoad: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
ModLoad: C:\Windows\Microsoft.NET\Framework\v4.0.30319\diasymreader.dll
ModLoad: NLog.dll
 .......................................
ModLoad: C:\Windows\assembly\NativeImages_v4.0.30319_32\System.Runteb92aa12#\ad1a5e8488b493088c4317191604dc81\System.Runtime.Serialization.ni.dll
(730.4a4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.

问题是:如何将处理对象从.Net传递到非托管应用程序中? p.s.附加信息. 缺乏信息是这里的主要问题. Oracle提供的文档非常混乱且不完整. 如果有人对应用于信息检索的工作有任何疑问...这是原始文档的链接

Question is: How to pass handle to managed object from .Net in to unmanaged application? p.s. Additional info. Lack of information is main problem here. Documentation provided by Oracle are very confusing and incomplete. If anyone have some doubts about efforts that have been applied to information retrieval... Here is a link to original documentation https://docs.oracle.com/cd/E14004_01/books/PDF/SiebCTIAdm.pdf (starts from 260p.).

但是我有一些例子是大约10年前用Delphi写的. 我将从那里提供一些我认为可能有用的代码. 1)函数CreateISCDriverInstance(在TicISCCommunicationDriver类中)

But I have some example which were written in Delphi about 10 years ago. I'll provide some code from there which I think may be useful. 1) Function CreateISCDriverInstance(in TicISCCommunicationDriver class)

function CreateISCDriverInstance(const AMediaTypeStr, ALanguageCode,
  AConnectString: PWideChar; const AParams: TISCNamedParamList;
  out ADriverHandle: THandle): HRESULT;
begin
  try
    ADriverHandle := TicISCCommunicationDriver.CreateInstance(AParams).Handle;
    Result := SC_EC_OK;
  except
    Result := SC_EC_DRIVER_CREATION_ERR;
  end;
end;

2)部分或TicISCCommunicationDriver定义:

2) Part or TicISCCommunicationDriver defenition:

TicISCCommunicationDriver = class(TObject)
  strict private
    class var
      FInstance: TicISCCommunicationDriver;
      ...
    var
      FHandle: THandle;
      ...

3)构造函数: 类函数TicISCCommunicationDriver.CreateInstance(const AParams:TISCNamedParamList):TicI​​SCCommunicationDriver; 开始 如果未分配(FInstance),则 FInstance:= TicISCCommunicationDriver.Create(AParams); 结果:= FInstance; 结束;

3) Constructor: class function TicISCCommunicationDriver.CreateInstance(const AParams: TISCNamedParamList): TicISCCommunicationDriver; begin if not Assigned(FInstance) then FInstance := TicISCCommunicationDriver.Create(AParams); Result := FInstance; end;

constructor TicISCCommunicationDriver.Create(const AParams: TISCNamedParamList);
var
  IsDebug: boolean;
begin
  inherited Create;
  FHandle := THandle(@Self);
    ...
   end;

我从来没有在Delphi中开发任何东西,但是,据我所知-这是在Delphi上实现的单例模式.而FHandle:THandle只是TicISCCommunicationDriver实例的句柄. 在Google中搜索后,我发现THandle是标识全局分配的动态内存对象的句柄. p.p.s. 我也尝试使用HandleRef找到解决方案,但也没有帮助.

I've never developed anything in Delp but, as far as i can get - it's singleton pattern implemented on Delphi. And FHandle:THandle it's just a handle to instance of TicISCCommunicationDriver. After search in Google i found that THandle it's a handle identifying a globally allocated dynamic memory object. p.p.s. Also i tried to find the solution using HandleRef, but it doesn't helped too.

推荐答案

GCHandle对于该参数没有位置.这用于固定托管内存之类的操作.该句柄由非托管代码提供.它是一个不透明的指针.

GCHandle has no place for that parameter. That's used for operations like pinning managed memory. This handle is provided by the unmanaged code. It is an opaque pointer.

我从您的另一个问题中得知,Delphi代码有点古怪,将其声明为THandle.从语义上讲这是关闭的,因为我认为该句柄实际上不是Win32 HANDLE.

The Delphi code, which incidentally I know from your other question to be a little wonky, declares this as a THandle. That's semantically off because I don't think this handle is really a Win32 HANDLE.

但是,可以肯定地说此句柄只是一个IntPtr.您完全按照我在上一个问题中所述的方法处理该参数:

However, it is safe to say that this handle is just an IntPtr. You deal with that parameter exactly as I stated in your previous question:

out IntPtr handle

该函数产生其状态的句柄,以处理该函数刚创建的事物.您会记住它,然后将其传递给需要该句柄的其他函数.

The function yields a handle to its state, to the thing that the function just created. You remember it and then pass it on to the other functions that need that handle.

这篇关于使用PInvoke将句柄传递给托管对象时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆