C#调用非托管C++;返回正方形符号串 < >我有一些C++代码调用到非托管C++ DLL中。我调用的方法旨在接受字符串作为引用。要处理此问题,我将在StringBuilder中传递,否则会出现StackOverflowException
这可以正常工作,但在某些调用中,从非托管代码返回的字符串是一个混乱的字符串,如下所示:ŸE~,Ê。我知道这一定与编码有关,但我已经尝试了下面列出的几种方法,但没有任何效果。这在其他人编写的VB.Net代码中并不是一个问题 以下是我尝试过的: 1.我使用的是:[DllImport(“dmphnx32.dll”)],但尝试了所有字符集选项都没有成功C#调用非托管C++;返回正方形符号串 < >我有一些C++代码调用到非托管C++ DLL中。我调用的方法旨在接受字符串作为引用。要处理此问题,我将在StringBuilder中传递,否则会出现StackOverflowException,c#,c++,encoding,unmanaged,dllimport,C#,C++,Encoding,Unmanaged,Dllimport,这可以正常工作,但在某些调用中,从非托管代码返回的字符串是一个混乱的字符串,如下所示:ŸE~,Ê。我知道这一定与编码有关,但我已经尝试了下面列出的几种方法,但没有任何效果。这在其他人编写的VB.Net代码中并不是一个问题 以下是我尝试过的: 1.我使用的是:[DllImport(“dmphnx32.dll”)],但尝试了所有字符集选项都没有成功 尝试使用Encoding.Default.GetBytes、Encoding.ASCII、Encoding.Unicode和其他内容,但未成功 我没有任
[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;
}
谢谢,
Corey您可以尝试使用IntPtr和封送处理类,而不是StringBuilder 所以,它看起来是这样的:
[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类型的编码)。稍微试验一下,看看Marshal.PtrToString。。。一个是工作的,虽然ANSI应该工作,因为这是大多数C++库使用的。
OK,我看到了你的问题。您需要为StringBuilder分配一个容量,您不能只使用默认值。
在我尝试了前两个答案并了解到它们没有帮助后,我知道肯定还有其他问题值得怀疑。我在我的应用程序中的其他地方发现了一个小错误,我在非托管代码中丢失了一个初始化参数。这导致了我奇怪的编码字符串 谢谢你的帮助,Corey < /P>你能发布你试图调用的C++方法的声明吗?如果C++对你可用(而且小到可以发布),那么就发布它。我仍然得到相同的奇怪的编码值。我尝试了这种方法并尝试了不同类型的编码,但我仍然得到了我的编码字符串。我想知道还有什么事情发生吗?你注意到C++版本使用“句柄”作为HWND,你把它当作int使用吗?据我所知,HWND是一个Int64(长)。我唯一能想到的另一件事是,也许你有一个对齐问题。