当前位置: 首页 > wzjs >正文

最新天气预报最新消息品牌关键词优化哪家便宜

最新天气预报最新消息,品牌关键词优化哪家便宜,深圳专业手机网站建设,广州番禺职业技术学院门户网站背景: Xt160Api, 之前在windows下用.net调用,没有任何问题。 但是移植到Linux去后,.net程序 调用 init(config_path) 总是报错 /root/test 找不到 traderApi.ini (/root/test 是程序目录) 然后退出程序 解决过程: 于是考虑是不是参数传错了&…

背景
Xt160Api, 之前在windows下用.net调用,没有任何问题。
但是移植到Linux去后,.net程序 调用 init(config_path) 总是报错 /root/test 找不到 traderApi.ini (/root/test 是程序目录) 然后退出程序

解决过程:
于是考虑是不是参数传错了,但是无论这个参数是什么, 报错内容始终如此。
甚至某些情况下,比如加了几句Console.WriteLIne(app_exe_folder) 还会出现段错误,这个问题至今也没想明白。
尊崇爱因斯坦的指导意见: 不要做相同的事情,期望得到不同的结果
用Visual Studio远程编译 Linux C++ 程序 调用 init函数 。 发现 confg_path 可以被识别,如果config_path下没有ini存在,他会报错没有在 config_path下找到 traderApi.ini 而不是 .net 那样永远显示: /root/test 下找不到traderApi.ini
这个让我极度困惑,我甚至尝试用 unsafe模式,硬编码字符串,传入 init的参数, 但是输出依旧。

我甚至认为这个api收到了 .net 的路径影响,因为linux调用 .net 形如 dotnet ./MyApp.dll 这个api在查找ini时用的是 dotnet 的路径,而显示的时候用的是dll的路径。(最后证明这个逻辑完全不对) 所以我在 dotnet 的文件夹下添加了 traderApi.ini , 依旧如故。

于是我又转而认为2点,

  1. api 的指针有问题,可能我的EntryPoint写错了?
  2. 虚表有问题,什么地方写错了?但是 init 函数是第3个函数,前2个是 析构函数,setCallbak 函数, 之后就是 init 函数

非常疑惑,而且沮丧,觉得很无聊,甚至在想是不是.net core 3.1的bug? 要不要换.net8试试? 搞得我很烦。
但是还是掩盖烦躁,开始用c++写 so文件 TestSO.so
如下:
test.cpp:

#include "mylib.h"
#include "XtTraderApi.h"
#include<cstdio>extern "C"
{void MyInit(void* api, const char* path){printf("%s", "start start!!!");auto xt_api = (xti::XtTraderApi*)api;xt_api->init(path);printf("%s", path);printf("ok ok ok\r\n");		//auto xtApi = (xti::XtTraderApi*)api;//xtApi->init(path);}
}

mylib.h

#ifndef MYLIB_H
#define MYLIB_H#ifdef __cplusplus
extern "C" 
{
#endif// 声明 MyInit 函数void MyInit(void* api, const char* path);#ifdef __cplusplus
}
#endif#endif // MYLIB_H

远程编译后,把 so文件送入 /lib64 (映射后实际位置为/usr/lib64)
然后 ldconfig
最后用 ldconfig -p | grep libTest确认生效:
在这里插入图片描述
接下去先用c++ 程序调用TestSO.so, 传入 api的地址和config_path,一切正常!
说明so文件运行正确。
接下去就用C#程序调用TestSO.so, 传入 .net 中根据EntryPoint得到的 api地址,这次在so文件中调用 init函数居然一切正常!!
这样我们几乎就确定了那个我们认为最不可能有问题的 虚表 问题了!
但是怎么会?如果虚表有问题,说明函数地址是错的,调用不应该是直接崩溃,或者输出的是其他信息,怎么会返回 init函数的错误信息呢?
觉得非常不可思议,不可能啊。(但是,就是如此,原因很难想象)

如果虚表有问题,我还是只能从 C++ 是如何调用 api->init 的代码,反汇编,看看 init 在虚表中的位置。
Visual Studio 支持 Linux 远程反汇编 nice!
api->init 的汇编如下:

0x0000000000400fc1 e8 8a fe ff ff       callq  0x400e50 <_ZN3xti11XtTraderApi17createXtTraderApiEPKc@plt> 
0x0000000000400fc6 48 89 45 c0          mov    %rax,-0x40(%rbp) 
0x0000000000400fca 48 8b 45 c0          mov    -0x40(%rbp),%rax 
0x0000000000400fce 48 8b 00             mov    (%rax),%rax 
0x0000000000400fd1 48 83 c0 18          add    $0x18,%rax 
0x0000000000400fd1 48 83 c0 18          add    $0x18,%rax 
0x0000000000400fd5 48 8b 10             mov    (%rax),%rdx 
0x0000000000400fd8 48 8b 45 c0          mov    -0x40(%rbp),%rax 
0x0000000000400fdc be 80 7f 40 00       mov    $0x407f80,%esi 
0x0000000000400fe1 48 89 c7             mov    %rax,%rdi 
0x0000000000400fe4 ff d2                callq  *%rdx

注意这两句不知道为什么被Visual Studio 重复了2行,注意看他们地址是一样的,说明是一条指令,而不是两条指令。
而且这条语句极其重要,确定了init函数在虚表的位置。

0x0000000000400fd1 48 83 c0 18          add    $0x18,%rax 
0x0000000000400fd1 48 83 c0 18          add    $0x18,%rax 

神奇的是,deepseek直接把他们正确的识别为了1条语句。下面是他的解答:

This is a more complex snippet of x86-64 assembly code. Let’s break it down step by step:

  1. 0x0000000000400fc1 e8 8a fe ff ff callq 0x400e50 _ZN3xti11XtTraderApi17createXtTraderApiEPKc@plt

Address: 0x0000000000400fc1
Opcode: e8 8a fe ff ff

Instruction: callq 0x400e50

Description: This calls the function
_ZN3xti11XtTraderApi17createXtTraderApiEPKc located at address 0x400e50. The function name is mangled and corresponds to a C++ method
xti::XtTraderApi::createXtTraderApi(char const*). The @plt indicates
that this is a dynamically linked function via the Procedure Linkage
Table (PLT).

Purpose: This is likely creating an instance of the XtTraderApi class.

  1. 0x0000000000400fc6 48 89 45 c0 mov %rax,-0x40(%rbp)

Address: 0x0000000000400fc6

Opcode: 48 89 45 c0

Instruction: mov %rax, -0x40(%rbp)

Description: The return value of the createXtTraderApi function
(stored in rax) is moved into the memory location at -0x40 bytes
offset from the base pointer (rbp). This is likely storing the pointer
to the newly created XtTraderApi object in a local variable.

  1. 0x0000000000400fca 48 8b 45 c0 mov -0x40(%rbp),%rax

Address: 0x0000000000400fca

Opcode: 48 8b 45 c0

Instruction: mov -0x40(%rbp), %rax

Description: The pointer to the XtTraderApi object (stored at
-0x40(%rbp)) is loaded back into the rax register.

  1. 0x0000000000400fce 48 8b 00 mov (%rax),%rax

Address: 0x0000000000400fce

Opcode: 48 8b 00

Instruction: mov (%rax), %rax

Description: This dereferences the pointer in rax (which points to the
XtTraderApi object) and loads the value at that memory location into
rax. In C++ terms, this is likely accessing the vtable (virtual table)
pointer of the XtTraderApi object, which is typically the first member
of an object with virtual methods.

  1. 0x0000000000400fd1 48 83 c0 18 add $0x18,%rax

Address: 0x0000000000400fd1

Opcode: 48 83 c0 18

Instruction: add $0x18, %rax

Description: This adds 0x18 (24 in decimal) to the value in rax. Since
rax currently holds the vtable pointer, this is likely calculating the
address of a specific entry in the vtable. The offset 0x18 suggests
that this is the 4th entry in the vtable (assuming each entry is 8
bytes on a 64-bit system).

  1. 0x0000000000400fd5 48 8b 10 mov (%rax),%rdx

Address: 0x0000000000400fd5

Opcode: 48 8b 10

Instruction: mov (%rax), %rdx

Description: This dereferences the address in rax (which now points to
a specific vtable entry) and loads the value at that memory location
into rdx. This value is likely a function pointer corresponding to a
virtual method in the XtTraderApi class.

  1. 0x0000000000400fd8 48 8b 45 c0 mov -0x40(%rbp),%rax

Address: 0x0000000000400fd8

Opcode: 48 8b 45 c0

Instruction: mov -0x40(%rbp), %rax

Description: The pointer to the XtTraderApi object (stored at
-0x40(%rbp)) is loaded back into rax. This is likely preparing the this pointer for the virtual method call.

  1. 0x0000000000400fdc be 80 7f 40 00 mov $0x407f80,%esi

Address: 0x0000000000400fdc

Opcode: be 80 7f 40 00

Instruction: mov $0x407f80, %esi

Description: The immediate value 0x407f80 is moved into the esi
register. This is likely an argument being passed to the virtual
method.

  1. 0x0000000000400fe1 48 89 c7 mov %rax,%rdi

Address: 0x0000000000400fe1

Opcode: 48 89 c7

Instruction: mov %rax, %rdi

Description: The pointer to the XtTraderApi object (in rax) is moved
into rdi. In the System V AMD64 ABI, rdi is used for the first
argument to a function, which in this case is the this pointer for the
virtual method call.

  1. 0x0000000000400fe4 ff d2 callq *%rdx

Address: 0x0000000000400fe4

Opcode: ff d2

Instruction: callq *%rdx

Description: This calls the function whose address is stored in rdx.
Since rdx holds a function pointer from the vtable, this is invoking a
virtual method of the XtTraderApi object.

Summary:
A XtTraderApi object is created, and its pointer is stored on the stack.
The vtable pointer of the object is accessed.
A specific virtual method (at offset 0x18 in the vtable) is resolved.
The virtual method is called with the XtTraderApi object (this pointer) as the first argument and 0x407f80 as the second argument.
This is typical C++ behavior for calling a virtual method on an object. The vtable is used to dynamically resolve the correct method to call at runtime.

因此我们确定了 init 函数在虚表中的位置是 0x18 也就是24, 那么24/8 = 3 , 所以是 0,8,16,24 在虚表中是第4个!

但是,但是,我们的虚表显示,ini是第3个函数,也就是位置 16 的那个函数!? windows下也用这个虚表,而且我们其他工程都是虚表(windows与linux)一致的啊!
这是怎么回事!!!??
下面展示部分头文件,大家看看能明白怎么回事吗:

 class XT_API_EXPORT XtTraderApi{public:virtual ~XtTraderApi(){};/*** @brief 获取XtTraderApi实例* @param [in] address XtApiService监听端口*/static XtTraderApi* createXtTraderApi(const char* address);/*** @brief 设置数据回调对象* @param [in] pCallback XtTraderApiCallback类实例*/virtual void setCallback(XtTraderApiCallback* pCallback) = 0;/*** @brief 创建api实例,并进行初始化* @param [in] configFilePath 配置文件夹目录,默认是"../config",运行目录上一层的config下*/virtual bool init(const char* configFilePath = "../config") = 0;

你看, 析构函数,static函数, setCallback, init 但是 那个 static函数不可能写在虚表里啊,windows下就是被撇除的,所以是 析构函数,setCallback, init 这个次序啊。
但是,Linux的反汇编已经说了, init 的位置是 第4个函数!!也就是 static函数 也被算在虚表里了。LINUX 下!
服了,之前其他工程,头文件类声明中的确没有 static函数。。。。。。。
这个在 windows中和Linux中实现是不一样的!!!
所以我们回过头,再去看之前的错误,我们认为我们一直在调用init函数,其实调用的是 setCallback(*pCallback) 函数, 我们以为传入的是字符串,但是api认为你传入的是pCallback, 而且最 搞笑 的是, setCallback 函数会检查 traderApi.ini 是否被加载过,没有则显示的错误和 init 显示的错误一致!
这错误显示太没有逻辑了!直接误导我了几天!!!!!!
于是修改了虚表, all done!

http://www.dtcms.com/wzjs/296545.html

相关文章:

  • b2b网站流量建设营销自动化工具
  • 途牛网站大数据建设seo优化是怎么回事呢
  • 网站怎么做备份uc浏览器关键词排名优化
  • 创造与魔法官方网站做自己喜欢的事今日新闻最新事件
  • 岳麓区专业的建设网站公司seo标题优化
  • 做企业网站找谁引擎搜索是什么意思
  • 西安企业网站制作价格手机推广平台有哪些
  • 上海网站建设网页制作联系方式百度收录入口在哪里查询
  • 个人域名做邮箱网站seo下拉优化
  • 太仓市住房城乡建设局网站新站seo竞价
  • 浙江网站建设价位今天军事新闻最新消息
  • 做网站需要做什么页面新闻式软文经典案例
  • 合肥做网站维护的公司网络推广工作好做不
  • 群晖nas做网站服务器长沙靠谱关键词优化公司电话
  • 苏州h5网站建设价格百度 人工客服
  • 点胶喷嘴技术支持东莞网站建设企业网站模板源码
  • 新版wordpress头像广州seo排名收费
  • 网站建设学习内容软件推广是什么工作
  • 网站是否必须做可信网站认证推广营销策划方案
  • 门户网站内容天津百度百科
  • 网站制作 长沙2023年6月疫情情况
  • 兰溪高端网站建设公司google首页
  • 网站建设南宁seo网站运营
  • 网站秒杀怎么做哈尔滨seo
  • php企业网站开发教程b站推广网站2024
  • 网上团建智慧团建登录入口微信搜一搜排名优化
  • 松江区网站建设公司抖音搜索引擎优化
  • 自己做的网站背景怎么设置宁波seo关键词排名优化
  • 企业建设一个自己的网站多少钱外贸网络推广经验
  • 做网站在手机显示怎么很乱企业广告宣传