通过P/Ivoke在C#中传递结构指针(主体中包含字符指针)

通过P/Ivoke在C#中传递结构指针(主体中包含字符指针),c#,windows-ce,.net-cf-3.5,C#,Windows Ce,.net Cf 3.5,我有一个C语言的.DLL文件。该DLL中所有函数所需的主要结构如下所示 typedef struct { char *snsAccessID; char *snsSecretKey; char *snsPath; char *snsTopicName; char *snsTopicAmazonResourceName; char *snsDisplayName; char *sns

我有一个C语言的.DLL文件。该DLL中所有函数所需的主要结构如下所示

typedef struct
{
    char *snsAccessID;      
    char *snsSecretKey;     
    char *snsPath;          
    char *snsTopicName;     
    char *snsTopicAmazonResourceName; 
    char *snsDisplayName;   
    char *snsOwnerId;       
} snsTopic, *HSNS;
例如,其中一个函数如下所示:

BOOL SnsOpenTopic(char *accessID, char *secretKey, char *ownerId, char *path, char *topicName, char *displayName, HSNS *snsTopicHandle);
上面的所有字符指针都是输入参数

我正在WinCE6/7设备上使用C#with.NET CF 3.5

我尝试使用一个类,然后将指针传递给C函数所需的结构,如下所示:

public class HSNS
{
    public string snsAccessID;      
    public string snsSecretKey;     
    public string snsPath;          
    public string snsTopicName;     
    public string snsTopicAmazonResourceName; 
    public string snsDisplayName;   
    public string snsOwnerId;       
}

[DllImport("Cloud.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean SnsOpenTopic(string accessID, string secretKey, string ownerId, string path, string topicName, string displayName, ref HSNS snsTopicHandle);
使用上面的C#代码段会导致抛出NotSupportedException。我不知道上面的C代码有什么问题

我尝试过的另一件事是在C#中使用非托管代码

在上面的例子中,在调试中,我可以检查结构中的指针是否没有被填充,在调试视图中,我可以看到无效的引用。无法取消引用指针消息。其他函数因此而失败


对于上述场景,使用平台调用和编组的正确方法是什么。我试过在谷歌上搜索和堆栈溢出。没有找到与我类似的用例

我相信您使用IntPtr表示char*和“ref”表示您的结构

[DllImport("Cloud.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean SnsOpenTopic(string accessID, string secretKey, string ownerId, string path, string topicName, string displayName, ref HSNS snsTopicHandle);

[StructLayout(LayoutKind.Sequential)]
public struct HSNS
{
    public IntPtr snsAccessID;      
    public IntPtr snsSecretKey;     
    public IntPtr snsPath;          
    public IntPtr snsTopicName;     
    public IntPtr snsTopicAmazonResourceName; 
    public IntPtr snsDisplayName;   
    public IntPtr snsOwnerId;       
}
然后,当您想要访问结构结果时,需要将IntPtr封送到字符串


问题在于编码。NETCF3.5始终使用Unicode编码。我使用的DLL中的函数,期望字符指针指向ASCII而不是Unicode中的字符串

我是这样做的

unsafe public struct HSNS
{
    public char *snsAccessID;      
    public char *snsSecretKey;     
    public char *snsPath;          
    public char *snsTopicName;     
    public char *snsTopicAmazonResourceName; 
    public char *snsDisplayName;   
    public char *snsOwnerId;       
}

[DllImport("Cloud.dll", SetLastError = true)]
public unsafe static extern Boolean SnsOpenTopic(Byte* accessID, Byte* secretKey, Byte* ownerId, Byte* path, Byte* topicName, Byte* displayName, ref HSNS snsAcsTopic);

// Sample of encoding conversion
public Byte[] topicName = Encoding.ASCII.GetBytes("CSharpACSAlert\0");
然后使用下面的命令获取指针并修复它

fixed (Byte* ptrTopicName = &topicName[0])
我仍然有一些其他功能的工作问题,但两个主要功能已经开始工作

下面的两个帖子帮助很大


我试了你的建议。不起作用。结构中的指针仍然没有填充。这在调试中很清楚,并且在使用Marshal.PtrToStringBSTR(snsAcsTopic.snsDisplayName)时,会抛出一个NullException。@Sanchayan-如果不知道您的C代码,很难提供帮助。C中的字符数组是全局分配的吗?
System.Runtime.InteropServices.Marshal.PtrToStringAuto(snsTopicHandler.snsPath);
unsafe public struct HSNS
{
    public char *snsAccessID;      
    public char *snsSecretKey;     
    public char *snsPath;          
    public char *snsTopicName;     
    public char *snsTopicAmazonResourceName; 
    public char *snsDisplayName;   
    public char *snsOwnerId;       
}

[DllImport("Cloud.dll", SetLastError = true)]
public unsafe static extern Boolean SnsOpenTopic(Byte* accessID, Byte* secretKey, Byte* ownerId, Byte* path, Byte* topicName, Byte* displayName, ref HSNS snsAcsTopic);

// Sample of encoding conversion
public Byte[] topicName = Encoding.ASCII.GetBytes("CSharpACSAlert\0");
fixed (Byte* ptrTopicName = &topicName[0])