TL;DR:我有一个 Derived**,我将其作为 void* 用户数据存储在 Lua 中。然后我尝试将其恢复为基地**,但东西却损坏了。我能做些什么吗?还是这一切都是注定要失败的疯狂?
细节:
我在 Lua 和 C++ 之间来回传递一些数据,Lua 需要使用 void* 来存储用户数据(我使用 Lua 并不是太重要,除了它使用 void 指针)。到目前为止是有道理的。假设我有三个类,Base并且Derived继承Derived自Base。我提供给 Lua 的用户数据是一个指向指针的指针,如下所示:
template <typename T>
void lua_push(L, T* obj) {
T** ud = (T**)lua_newuserdata(L, sizeof(T*)); // Create a new userdata
*ud = obj; // Set a pointer to my object
// rest of the function setting up other stuff omitted
}
Run Code Online (Sandbox Code Playgroud)
当然,这是一个很好的模板化函数,因此我可以通过这种方式传递三种类型中的任何一种。稍后我可以使用另一个模板函数从 Lua 中获取我的用户数据,如下所示:
template <typename T>
T* lua_to(lua_State* L, int index) { …Run Code Online (Sandbox Code Playgroud) 几个学期回来我有一个课,我们写了一个非常基本的方案解析器,最后是一个解释器.在课程结束后,我将解析器转换为C++解析器,只要我没有对预处理器或宏做任何事情,我就可以很好地解析C++.我可以用它来读取我的类和函数,并做一些巧妙的事情,比如自动生成类读者或编写器,或者从文本文件中设置函数回调.
但是,我的计划非常有限.我确信我可以花一些时间来使它更健壮并做更多整洁的事情,但如果已经有更强大的工具可以做同样的事情,我不想花费时间和精力.我认为必须有这样的东西,因为解析器是编译器的重要组成部分,但我还没有看到专门用于自动代码生成的工具,这使得它很容易通过并使用代表类,函数和数据的数据结构.特别是C++的变量.有没有这样的工具?
编辑:
希望这将澄清我正在寻找的一点点.我在Visual Studio中作为预建步骤运行的程序.它读取我的源文件,列出类,它们的成员,它们的功能等,然后用它们来生成新的代码.目前我只是使用它来轻松读取和写入我的数据结构到纯文本文件,但我也可以做其他事情.文件读取器和编写器输出到普通的.cpp和.h文件,我将其包含在项目的其余部分中,就像我任何其他文件一样.我正在寻找的是做类似事情的工具,所以我可以决定是继续使用自己的还是转而使用更好的解决方案.我不是在寻找任何可以生成机器代码或编辑代码的东西.
这是我正在使用的数组库中的代码片段。这在Windows上运行良好,但是如果我在Linux上使用gcc进行编译(如果该函数崩溃),则可以正常运行。当试图缩小问题范围时,我向其添加了一条printf语句,并且代码停止崩溃。
void _arrayCreateSize( void ***array, int capacity )
{
(*array) = malloc( (capacity * sizeof(int)) + sizeof(ArrayHeader) );
((ArrayHeader*)(*array))->size = 0;
((ArrayHeader*)(*array))->capacity = capacity;
// printf("Test!\n");
*(char**)array += sizeof(ArrayHeader);
}
Run Code Online (Sandbox Code Playgroud)
取出printf后,它再次开始崩溃。我完全不知道为什么会这样。
我有一个模板化的类叫PooledResource.它为我处理像纹理和声音这样的事情,并确保我不会在事故中多次加载同一个.某种类型的资源将始终位于某个子目录中,我希望能够更轻松地加载它们,因此我决定添加一个静态变量来跟踪某种类型资源的根文件夹.
template <typename T>
class PooledResource
{
public:
// ...
static const char* PathPrefix;
static ResourceTable myResourceTable;
static void load(const char* filename)
{
// Any attempt to use PathPrefix in here causes a compilation error
// All I want to do is use PathPrefix and filename to get the full
// path do a file and load it.
}
};
template <typename T>
const char* PooledResource<T>::PathPrefix = NULL;
template <typename T>
typename PooledResource<T>::ResourceTable PooledResource<T>::myResourceTable;
Run Code Online (Sandbox Code Playgroud)
我的想法是我可以为各种类型使用typedef'd版本.例如,PooledTexture.hpp我会:
typedef …Run Code Online (Sandbox Code Playgroud) 我想制作一个特殊的版本,shared_ptr在创建或销毁它时执行特定的操作,但是我的计划似乎被实现了shared_ptr析构函数是非虚拟的,这意味着当我覆盖它时,我的指针永远不会被清除当它们的最后一个实例被销毁时.
想到的唯一选择是将这种行为建立在我想用于我的假设习惯的每个类中shared_ptr,这是不可行的(或者在某些情况下可能).
编辑:
我想要这个的原因是因为我想在lua中使用一些类作为userdata对象,并且我希望我使用这种方式的每个对象都有一个独特的fenv表,当所有引用都被清除时对象已被删除.我打算使用指针的地址,因为它们键入一个包含fenv表的表.
让我们说我有一个小部件可以有其他小部件作为孩子.我在Lua中创建了两个小部件,然后将一个小部件设置为另一个小部件,并删除对子小部件的所有lua引用(事实上它是一个用C++处理的子节点).GC现在可以随时运行并移除孩子.我不一定希望孩子运行它的析构函数,所以我想让它成为一个shared_ptr.这样,在Lua清理它之后,C++对象仍然可以使用它.如果我已将值或函数分配给它的fenv,我仍然希望能够访问它们.只有在删除对子窗口小部件的最终引用时,才能完全删除fenv tabled.
我正在尝试将指针强制转换为int(或unsigned int),无论我尝试什么它都不想工作.
我试过static_cast<intptr_t>(obj),reinterpret_cast<intptr_t>(obj)以及空调风格不同的组合铸就,intptr_t的,unsigned int的,和我包括stdint.h.从我读过的内容来看,我尝试过的很多东西中的一件应该可行.是什么赋予了?
我没有打扰包括代码,因为它正是我所描述的,但是既然你问过,我已经尝试了所有这些以及其他组合:
void myfunc(Foo* obj)
{
// ...
uintptr_t temp = reinterpret_cast<uintptr_t>(obj);
uintptr_t temp = static_cast<uintptr_t>(obj);
uintptr_t temp = (uintptr_t)obj;
intptr_t temp = reinterpret_cast<intptr_t>(obj);
intptr_t temp = static_cast<intptr_t>(obj);
intptr_t temp = (intptr_t)obj;
unsigned int temp = reinterpret_cast<unsigned int>(obj);
unsigned int temp = static_cast<unsigned int>(obj);
unsigned int temp = (unsigned int)obj;
// ...
}
Run Code Online (Sandbox Code Playgroud)
他们都给出完全相同的错误.
这段代码给了我输出:
The sqrt of 1.234 is: 1.52276 why is this diffrent from: 1.11086 1.11086
Run Code Online (Sandbox Code Playgroud)
为什么?
#include <iostream>
using namespace std;
template<typename T>
T sqrt(T x)
{
return x*x;
}
template<typename T>
void print_sqrt(T x)
{
double tmp = sqrt(x);
cout << "The sqrt of " << x << " is: " << sqrt<double>(x) << " why is this diffrent from: " << sqrt(x) << " " << tmp << endl;
}
int main()
{
print_sqrt<double>(1.234);
system("pause");
}
Run Code Online (Sandbox Code Playgroud)