我創建了一個簡單的SO例子,演示了將va_list作爲函數arg傳遞的各種方法。我試圖解決的問題是將va_list從共享對象回調到主模塊。將va_list作爲函數參數傳遞
/*libcode.vala shared library (libvala-0.38)*/
namespace SOTestLib {
public const string TESTSTR = "my test string";
public const string EXPECTFORMATSTR = "expect test:%s";
public const string EXPECTFORMATSTR_VA_ARG0 = "1==1";
public delegate bool delegatefnExpect (bool expression, string format, va_list valist);
public delegatefnExpect delfnExpect;
public delegate bool delegatefnString (string mystring);
public delegatefnString delfnString;
public string gTestStr;
public string gExpectResultStr;
private void show_string(string mystring) {
stdout.printf("show_string mystring[%s] gTestStr[%s]\n", mystring, gTestStr);
assert (mystring == gTestStr);
assert (delfnString != null);
delfnString(mystring);
}
private bool expect(bool expression, string sformat, ...) {
assert (delfnExpect != null);
assert (sformat == EXPECTFORMATSTR);
va_list _valist = va_list();
gExpectResultStr = sformat.vprintf (_valist);
stdout.printf("expect[%s]\n", gExpectResultStr);
return delfnExpect(expression, sformat , _valist);
}
private void my_printf (string format, ...) {
va_list va_list = va_list();
string res = format.vprintf (va_list);
stdout.puts (res);
}
public int run_demo() {
//REFER:https://valadoc.org/glib-2.0/string.vprintf.html
// Output: ``Shut up, K-9!``
my_printf ("Shut %s, %c-%d!\n", "up", 'K', 9);
gTestStr = TESTSTR;
show_string(TESTSTR);
expect(1 == 1, EXPECTFORMATSTR, EXPECTFORMATSTR_VA_ARG0);
return 0;
}
}
/*main.vala linked with libcode.so shared library (libvala-0.38)*/
using SOTestLib;
public bool cbfnString(string test_str) {
stdout.printf("cbfnString test_str[%s] gTestStr[%s]\n", test_str, gTestStr);
assert (test_str == gTestStr);
return true;
}
public bool cbfnExpect(bool expression, string format, va_list args) {
stdout.printf("cbfnExpect format[%s] format.length[%d]\n",
format, format.length);
assert (format == EXPECTFORMATSTR);
string res = format.vprintf(args);
assert (res != null);
stdout.printf("cbfnExpect res[%s] gExpectResultStr[%s]\n", res, gExpectResultStr);
assert(res == gExpectResultStr);
return expression;
}
static int main(string[] args) {
delfnString = (delegatefnString)cbfnString;
delfnExpect = (delegatefnExpect)cbfnExpect;
return run_demo();
}
這裏是運行測試的結果...
===========================================================================
---Run main --
===========================================================================
./stackoverflow/libcallback_strings/lib/libcallback_strings.exe
Shut up, K-9!
show_string mystring[my test string] gTestStr[my test string]
cbfnString test_str[my test string] gTestStr[my test string]
expect[expect test:1==1]
cbfnExpect format[expect test:%s] format.length[14]
cbfnExpect res[expect test:(null)] gExpectResultStr[expect test:1==1]
**
ERROR:/media/george/SharedData/Projects/Vala/LanguageServer/stackoverflow/libcallback_strings/main.vala:15:cbfnExpect: assertion failed: (res == gExpectResultStr)
stackoverflow/so_examples.mk:252: recipe for target 'libcallback_strings' failed
make: *** [libcallback_strings] Aborted
The terminal process terminated with exit code: 2
出於某種原因在cbfnExpect,va_list的參數表是不再有效。看起來好像va_list地址(或結構內的地址)只在共享庫中有效。這不正確/允許使用va_list嗎?