什么';这是一种很好的线程安全方法,可以将错误字符串从C共享库传回 我正在编写一个C共享库,用于内部使用(我将DLUN),把它应用到C++应用程序,如果这很重要的话。共享库通过JNI模块加载(除其他外)一些java代码,这意味着我需要在应用程序中智能处理的JVM可以产生各种形式的噩梦错误模式。此外,此库需要重新进入。在这种情况下,是否有将错误字符串传回的习惯用法,或者我是否被困在将错误映射到整数并使用printfs调试东西的过程中
谢谢 我想你可以像Windows一样使用PWideChars。它是线程安全的。您需要的是调用应用程序创建一个PwideChar,Dll将使用该PwideChar设置错误。然后,调用应用程序需要读取PWideChar并释放其内存。返回指向什么';这是一种很好的线程安全方法,可以将错误字符串从C共享库传回 我正在编写一个C共享库,用于内部使用(我将DLUN),把它应用到C++应用程序,如果这很重要的话。共享库通过JNI模块加载(除其他外)一些java代码,这意味着我需要在应用程序中智能处理的JVM可以产生各种形式的噩梦错误模式。此外,此库需要重新进入。在这种情况下,是否有将错误字符串传回的习惯用法,或者我是否被困在将错误映射到整数并使用printfs调试东西的过程中,c++,c,shared-libraries,C++,C,Shared Libraries,谢谢 我想你可以像Windows一样使用PWideChars。它是线程安全的。您需要的是调用应用程序创建一个PwideChar,Dll将使用该PwideChar设置错误。然后,调用应用程序需要读取PWideChar并释放其内存。返回指向静态常量char[]对象的指针。这始终是处理错误字符串的正确方法。如果需要本地化,则返回指向只读内存映射的本地化字符串的指针。R.有一个很好的答案(使用static const char[]),但是如果要使用各种语言,我喜欢使用枚举来定义错误代码。这比一些将一组名
静态常量char[]
对象的指针。这始终是处理错误字符串的正确方法。如果需要本地化,则返回指向只读内存映射的本地化字符串的指针。R.有一个很好的答案(使用static const char[]),但是如果要使用各种语言,我喜欢使用枚举来定义错误代码。这比一些将一组名称定义为int值要好。在C中,如果您不需要担心国际化(I18N)或本地化(L10N),那么指向常量数据的指针是提供错误消息字符串的好方法。但是,您经常会发现错误消息需要一些支持信息(例如无法打开的文件名),而常量数据实际上无法处理这些信息
考虑到I18N/L10N,我建议将每种语言的固定消息字符串存储在一个适当格式的文件中,然后使用在分叉任何线程之前将文件“读取”到内存中。这样映射的区域应视为只读(在调用mmap()
时使用PROT\u read
)
这避免了复杂的内存管理问题,并避免了内存泄漏
考虑是否提供可以调用以获取最新错误的函数。它可以有一个原型,例如:
int get_error(int errnum, char *buffer, size_t buflen);
我假设错误号是由其他函数调用返回的;然后,库函数查阅它拥有的关于当前线程和返回到该线程的最后一个错误条件的任何线程安全内存,并将适当的错误消息(可能被截断)格式化到给定的缓冲区中
使用C++,可以从错误报告机制返回(引用)标准字符串;这意味着您可以格式化字符串以包含文件名或其他动态属性。收集信息的代码将负责释放字符串,这不是因为C++具有的析构函数而导致的问题。您可能仍然希望使用
mmap()
加载消息的格式字符串
您确实需要小心加载的文件,尤其是用作格式字符串的任何字符串。(此外,如果您处理的是I18N/L10N,您需要考虑是否使用“
n$
符号来允许参数重新排序;您还需要考虑不同文化/语言的不同规则,即句子中单词的呈现顺序。)我对这个问题的处理方法与其他人略有不同。他们没有错,只是我不得不努力解决这个问题的另一个方面
errno.h
代码显示了错误的良好分类;事实上,如果您可以重用这些代码(或者只是传递它们,例如,如果您的所有错误最终都来自系统调用),那么就这样做。
- 不要复制
本身。如果可能,直接从可能失败的函数返回错误代码。如果不可能,请在state对象上使用errno
方法。你有一个状态对象,是吗GetLastError()
- 翻译这些字符串可能合适,也可能不合适。如果它们是开发人员只读的,就不用麻烦了。但是如果你需要向最终用户展示它们,那么是的,你需要翻译它们
- 这些字符串的未翻译版本实际上应该只是字符串常量,因此您没有分配问题。但是,不要浪费时间和精力编写自己的翻译基础设施。使用
- 例如,如果系统调用失败直接导致库产生自己设计的错误代码,则状态对象需要返回在系统调用失败后立即观察到的
值、所涉及的文件名(如果有)以及理想情况下系统调用本身的名称的方法。人们常常会弄错这一点——例如,SQLite,一个设计良好的API,没有公开errno
值或文件名,这使得很难区分“数据库上的文件权限错误”和“代码中有错误”errno
- 扭曲API(例如使用out参数),以便