문제

C# 응용 프로그램에서 C로 작성된 DLL의 메소드를 호출하려고합니다. 내가 통화를 구현 한 방법은 다음과 같습니다.

-> C 메소드 서명 : (제 3 부 회사에서)

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;
        }
    }

그리고 나는 그것을 얻는다 Win32Exception : 1008- 존재하지 않는 토큰을 참조하려는 시도가 이루어졌습니다.

문제는 관리되지 않은 (C)와 관리 (C#) 코드 사이의 문자열 변환에 있어야한다는 것을 알고 있습니다. 내가 수정하면 제본 또는 logpath 타이핑 할 매개 변수 SBYTE, 그것은 어떤 오류도 제공하지 않습니다. 그러나이 방법은 텍스트 (문자열)를 기대하기 때문에 SBYTE 변수를 기대하기 때문에 텍스트를 방법에 어떻게 전달할 수 있는지 모르겠습니다 ...

나는 내가 같은 것을 사용해야한다는 것을 알고있다. 마샬, 그러나 나는 몇 가지 옵션을 시도했지만 성공하지 못했습니다.

아무도 내가 뭘 잘못하고 있는지 말해 줄 수 있습니까 ??

매우 감사합니다!!


콜백 정의는 다음과 같습니다.

 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 메소드가 "ref"매개 변수를 기대하고 있다는 것입니다. 전화 ss_initialize 실행을 첨부합니다 ProcessMessage 콜백 함수. 이 기능에서는 ss_initialize에서 수정 된 매개 변수 (Ref)를 얻을 수 있어야합니다 ...

코드가 어떻게 구성되어야한다고 생각하십니까?

고맙습니다!!

도움이 되었습니까?

해결책

바인딩 및 logpath에 심판을 사용할 필요는 없습니다. 그들은 const char*이며 변하지 않을 것입니다.

콜백의 해당 응답 세미는 단일 문자열이 아닌 문자열 배열 (char **)을 반환합니다. 응답 크기는 아마도 배열의 깊이를 나타냅니다. [Marshalas (unamangedtype.lparray, arraysubtype = unmanagedtype.lpstr)] string [] 대신 시도해보십시오.

다른 팁

마샬링 문자열의 경우 통과하지 않습니다 ref string, 단지 string. 또한 각 문자열을 장식해야합니다 [MarshalAs( UnmanagedType.LPStr)] 지시하기 위해, 당신은 ascii chars를 포함하는 줄을 통과하고 있고 그것이 종료되었습니다.
편집 : 비슷한 실수를 할 수 있으므로이 콜백 절차에 대한 정의를 제공 할 수 있습니다.

고맙습니다 라 바데 그리고 r ubben, 당신의 도움이 합쳐졌습니다!

결국, 그것은 매개 변수의 Ref 절을 올바르게 제어하고 Marshalas 태그를 사용하는 것입니다. C 부분에서 "const char*"인 매개 변수에는 실제로 Ref 태그가 필요하지 않습니다. 또한 문자열 매개 변수에 [Marshalas (UnmanagedType.lpstr)]를 사용했습니다. 그게 다야!

추신 : stackoverflow.com은 놀랍습니다! 나는 이미 검색을 통해 다른 문제에 대한 많은 답을 찾았습니다. 이것은 나의 첫 번째 게시물이며 나는 이것에 대한 빠른 답변에 놀랐습니다. 모든 직원 팀과 회원들에게 축하드립니다! ;)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top