我想要呼吁的一种方法从DLL C编写,从我的C#应用程序。这里是我已经实现了该呼叫:

-->C的方法签署:(从第三部分公司)

Int16 SSEXPORT SS_Initialize(Uint16 ServerIds[], Uint16 ServerQty, const char PTR *Binding, const char PTR *LogPath, Uint16 LogDays, Int16 LogLevel,
Uint16 MaxThreads, Uint16 ThreadTTL, Int16 (CALLBACK *ProcessMessage)(Uint16, const char PTR *, Uint32, char PTR **, Uint32 PTR *, Int16 PTR *));

-->C类型的定义:

#ifndef _CSISERVERTYPES_
#define _CSISERVERTYPES_

#if defined(OS_NT)

#define CALLBACK __stdcall 
#define SSEXPORT __stdcall
#define PTR      

typedef char                Int8;
typedef unsigned char       Uint8;
typedef short               Int16;
typedef unsigned short      Uint16;
typedef long                Int32;
typedef unsigned long       Uint32;
typedef unsigned char       Byte;
typedef unsigned short      Word;
typedef unsigned long       Dword;
typedef short               Bool;

#endif

typedef Int16 (CALLBACK *PM_Function)
        (Uint16,const char PTR *,Uint32,char PTR **,Uint32 PTR *,Int16 PTR *);

#define SS_OK               0
#define SS_NOT_INIT         -1
#define SS_PROC_ERR         -2
#define SS_ERR_TCP_SRV      -3
#define SS_ERR_OUT_MEM      -4

#ifndef NULL
#define NULL                0
#endif

#endif

-->C#DLL方法宣言:

[DllImport("CSITCPServer.dll", SetLastError = true)]
    static extern Int16 SS_Initialize(
        UInt16[] ServerIds,
        UInt16 ServerQty,
        ref string Binding,
        ref string LogPath,
        UInt16 LogDays,
        Int16 LogLevel,
        UInt16 MaxThreads,
        UInt16 ThreadTTL,
        ProcessMessageCallback callback);

方法的呼吁:

public static void Call_SS_Initialize()
    {   
        Int16 ret;
        UInt16[] serverIds = new UInt16[] { 2020, 2021 };
        string binding = "";
        string logPath = "";

        try
        {
            ret = SS_Initialize(
                serverIds,
                Convert.ToUInt16(serverIds.ToList().Count),
                ref binding,
                ref logPath,
                10,
                0,
                256,
                300,
                ProcessMessage);

            Console.WriteLine("Call_SS_Initialize() -> Result of SS_Initialize:  {0}", ret.ToString());
        }
        catch (Exception ex)
        {
            Int32 err = Marshal.GetLastWin32Error();
            throw new Win32Exception(err);
            //throw;
        }
    }

然后我得到的 Win32:1008-尝试参考标记不存在的

我知道这个问题必须在字符串转换之间的托管(C)和管理(C#)的代码。如果我修改 结合LogPath 参数类型 符号字节, 它没有给任何错误。但是,由于该方法的期望对文本(string),我不知道我如何可以通过文本的方法,因为它需要一个符号字节的变量...

我知道,我可能要用的东西喜欢 MarshalAs, 但是我已经尝试一些选项并没有任何成功。

谁能告诉我什么是我做错了什么??

非常感谢你!!


这里是回的定义:

 public delegate Int16 ProcessMessageCallback(
        UInt16 ServerId,
        [MarshalAs(UnmanagedType.LPStr)] ref string RequestMsg,
        UInt32 RequestSize,
        [MarshalAs(UnmanagedType.LPStr)] ref string ResponseMsg,
        ref UInt32 ResponseSize,
        ref Int16 AppErrCode);

事情是这C DLL方法期待一个"参考"的参数。呼叫 SS_Initialize attachs的执行 ProcessMessage 回呼功能。在这个功能我需要能够得到修改的参数(ref)从SS_Initialize...

能不能请你表明你怎么认为的代码结构应?

谢谢你!

有帮助吗?

解决方案

你不需要使用的参考结合和LogPath;他们是const char*和也不会改变。

这ResponseMessage在回调会返回一系列的串,(char**)不仅仅是一个单一串。响应大会表示深度的阵列。尝试[MarshalAs(UnamangedType.LPArray,ArraySubType=UnmanagedType.LPStr)]串[]替代。

其他提示

为调集串你不通过 ref string, ,只是 string.此外,你应该每一个装饰用的字符串 [MarshalAs( UnmanagedType.LPStr)] 要表明,你是通过串包含ascii文字,它是空终止。
编辑:你能不能也给你的定义,这回过程中,你可以作出类似的错误。

谢谢你 RavadreR Ubben, ,您的帮助相结合的伎俩!!

在结束,它是所有关于控制适当参考条款的参数和使用MarshalAs标签。的参数,作为"const char*"在C部分真的不需要的参考标签。我也使用[MarshalAs(UnmanagedType.LPStr)]对于串的参数。这就是它!

ps:Stackoverflow.com 是惊人的!我已经发现了很多的回答其他的问题在这里,只是通过搜索。这是我的第一篇文章我很惊讶的快速回复我有这一个。祝贺所有工作人员和成员!;)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top