C# 관리되지 않는 C ++의 전화 통화 정사각형 정사각형 문자열 기호
문제
관리되지 않는 C ++ DLL로 C# 코드를 호출하는 것이 있습니다. 내가 호출하는 방법은 문자열을 Ref. 이것을 처리하기 위해 나는 StringBuilder를 통과 시키면, 그렇지 않으면 stackoverflowexception이 있습니다.
이것은 잘 작동하지만 일부 호출에서는 관리되지 않는 코드에서 돌아 오는 문자열이 다음과 같은 뒤죽박죽 문자열입니다. Øÿe ~., ê. 나는 이것이 인코딩과 관련이 있어야한다는 것을 알고 있지만 아래에 나열된 몇 가지를 시도했지만 아무것도 작동하지 않습니다. 이것은 VB.NET 코드에서 다른 사람이 비슷한 일을하기 위해 작성한 문제가 아닙니다.
내가 시도한 내용은 다음과 같습니다. 1. 나는 이것을 사용하고 있습니다 : [dllimport ( "dmphnx32.dll")], 성공하지 않고 모든 숯 옵션을 시도했습니다.
- encoding.default.getBytes, encoding.ascii, encoding.unicode 및 나머지는 성공하지 못한 상태로 사용하려고 시도했습니다.
C ++에 대한 경험이 없으므로 실제로 도움을 사용할 수 있습니다.
다음은 dllimport 방법입니다.
[DllImport("dmphnx32.dll")]
public static extern int PhxQueryDataAttributes(int handle,
StringBuilder lTableName,
StringBuilder lColumnName,
ref short lIteration,
ref short type,
ref short maxLen,
ref short endorsement,
StringBuilder endorsementId);
C ++ 코드는 다음과 같습니다.
short DMEXP PhxQueryDataAttributes(HWND handle,
char *lTableName,
char *lColumnName,
short *lIteration,
short *Type,
short *MaxLen,
short *Endorsement,
char *EndorsementID)
{
handle = PhxInfo.HiddenHwnd;
strcpy(lTableName, PhxInfo.TableName);
strcpy(lColumnName, PhxInfo.ColumnName);
*Type = PhxInfo.PhnxDataType;
// max len
*MaxLen = PhxInfo.MaxDataLen;
*Endorsement = PhxInfo.Endorsement;
strcpy(EndorsementID, PhxInfo.EndorsementID);
// determine which table we need the iteration of
*lIteration = PhxIterationArray[PhxInfo.sEffectiveTableID];
return SUCCESS;
}
다음은 관리되지 않는 코드로 호출되는 C# 코드입니다.
public int PhxQueryDataAttributes(int handle, ref string lTableName, ref string lColumnName,
ref short lIteration, ref short type, ref short maxLen, ref short endorsement,
ref string endorsementId)
{
var sbTableName = new StringBuilder();
var sbColName = new StringBuilder();
var sbEndId = new StringBuilder();
var ret = RatingProxy.PhxQueryDataAttributes(handle, sbTableName, sbColName,
ref lIteration, ref type, ref maxLen, ref endorsement, sbEndId);
lTableName = sbTableName.ToString();
lColumnName = sbColName.ToString();
endorsementId = sbEndId.ToString();
return ret;
}
고마워요, 코리
해결책 3
처음 2 개의 답변을 시도하고 그들이 도움이되지 않는다는 것을 알게 된 후, 나는 다른 것이 의심되어야한다는 것을 알았습니다. 내 앱의 다른 곳에서 작은 버그를 발견하여 실제로 관리되지 않는 코드에서 초기화 매개 변수가 누락되었습니다. 이것은 이상하게 인코딩 된 문자열을 유발했습니다.
도와 주셔서 감사합니다, Corey
다른 팁
좋아, 나는 당신의 문제를 본다. 당신은 용량을 할당해야합니다 StringBuilder
, 기본값 만 사용할 수 없습니다.
StringBuilder 대신 intptr 및 Marshal 클래스를 사용해 볼 수 있습니다.
따라서 다음과 같습니다.
[DllImport("dmphnx32.dll")]
public static extern int PhxQueryDataAttributes(int handle,
IntPtr lTableName,
IntPtr lColumnName,
ref short lIteration,
ref short type,
ref short maxLen,
ref short endorsement,
IntPtr endorsementId);
호출 코드는 다음과 같습니다.
public int PhxQueryDataAttributes(int handle, ref string lTableName, ref string lColumnName,
ref short lIteration, ref short type, ref short maxLen, ref short endorsement,
ref string endorsementId)
{
var sbTableName = Marshal.AllocHGlobal(1024);//Change these to the max length possible for each string.
var sbColName = Marshal.AllocHGlobal(1024);
var sbEndId = = Marshal.AllocHGlobal(1024);
var ret = RatingProxy.PhxQueryDataAttributes(handle, sbTableName, sbColName,
ref lIteration, ref type, ref maxLen, ref endorsement, sbEndId);
lTableName = Marshal.PtrToStringAnsi(sbTableName);
lColumnName = Marshal.PtrToStringAnsi(sbColName);
endorsementId = Marshal.PtrToStringAnsi(sbEndId);
return ret;
}
이렇게하면 올바른 인코딩을 지정할 수 있습니다 (UTF 유형 인코딩이라고 가정하는 문자열 빌더로 수행 할 수 없습니다). 약간의 실험을하고 어떤 원수를 확인하십시오. ptrtoString ... ANSI는 작동하지만 대부분의 C ++ 라이브러리가 사용하기 때문입니다.