gpt4 book ai didi

C#:将字符串编码为 utf8 char*

转载 作者:行者123 更新时间:2023-11-30 22:16:22 25 4
gpt4 key购买 nike

<分区>

背景

我正在尝试基于修改后的 libspotify.net ( http://libspotifydotnet.codeplex.com/ ) 编写高级 libspotify 包装器。由于 libspotify.net 只是一个薄的(并且完全被窃听......)pinvoke 层,它不处理 libspotify 使用的 utf8 编码。

我的想法是将字符串转换为 byte[] 并适本地更改签名。

我有这个原生结构:

typedef struct sp_session_config {
int api_version;
const char *cache_location;
const char *settings_location;
const void *application_key;
size_t application_key_size;
const char *user_agent;
const sp_session_callbacks *callbacks;
void *userdata;
bool compress_playlists;
bool dont_save_metadata_for_playlists;
bool initially_unload_playlists;
const char *device_id;
const char *proxy;
const char *proxy_username;
const char *proxy_password;
const char *ca_certs_filename;
const char *tracefile;

} sp_session_config;

工作版本:

    [DllImport("libspotify")]
public static extern sp_error sp_session_create(ref sp_session_config config, out sp_session sessionPtr);

public struct sp_session_config
{
public int api_version;
public IntPtr cache_location;
public IntPtr settings_location;
public IntPtr application_key;
public uint application_key_size;
public IntPtr user_agent;
public IntPtr callbacks;
public IntPtr userdata;
public bool compress_playlists;
public bool dont_save_metadata_for_playlists;
public bool initially_unload_playlists;
public IntPtr device_id;
public IntPtr proxy;
public IntPtr proxy_username;
public IntPtr proxy_password;
public IntPtr ca_certs_filename;
public IntPtr tracefile;
}

此版本将工作交给了使用该库的开发人员。

我的版本:

    public struct sp_session_config_internal
{
public int api_version;
public byte[] cache_location;
public byte[] settings_location;
public byte[] application_key;
public uint application_key_size;
public byte[] user_agent;
public IntPtr callbacks;
public IntPtr userdata;
public bool compress_playlists;
public bool dont_save_metadata_for_playlists;
public bool initially_unload_playlists;
public byte[] device_id;
public byte[] proxy;
public byte[] proxy_username;
public byte[] proxy_password;
public byte[] ca_certs_filename;
public byte[] tracefile;
}


[DllImport("libspotify", EntryPoint="sp_session_create")]
private static extern sp_error sp_session_create_internal(ref sp_session_config_internal config, out sp_session sessionPtr);
public static sp_error sp_session_create(ref sp_session_config config, out sp_session sessionPtr)
{
sp_session_config_internal config_internal = new sp_session_config_internal();
config_internal.api_version = config.api_version;
config_internal.application_key = config.application_key;
config_internal.application_key_size = (uint)config.application_key.Length;
config_internal.ca_certs_filename = SH.StringToUtf8Bytes( config.ca_certs_filename);
...
var err = sp_session_create_internal(ref config_internal, out session);
...
}

运行时,这会在 libspotify 中产生以下错误:访问冲突读取位置 0x000001c0我用谷歌搜索并在某处读到有时只有第一个数组元素被复制。我尝试用

装饰所有数组
        [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1)]

这给出了异常“无法编码‘sp_session_config_internal’类型的字段‘cache_location’:无效的托管/非托管类型组合(数组字段必须与 ByValArray 或 SafeArray 配对)。”

tl;dr

使用 IntPtr 和手动编码的复杂解决方案有效,使用 utf8 字符串的字节数组的更简单解决方案在库读取时会产生访问冲突。有没有比使用 intptr 手动编码更简单的方法?

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com