C 如何在VisualStudio项目中引用用户定义段的开头?

C 如何在VisualStudio项目中引用用户定义段的开头?,c,visual-c++,linker,symbols,segment,C,Visual C++,Linker,Symbols,Segment,我正在努力转换一个与gnu工具链的ld链接的C程序 使其作为visual studio(2005)项目编译。 程序将.data符号放在不同的段中,并在 初始化阶段它在段之间复制数据。指向 段的开始和结束在ld链接器脚本中定义 我了解如何将变量定位到不同的、用户定义的 段,但我还没有弄清楚如何定义链接器常量 例如"我的"段的"开始",或者是否有类似链接器的东西 VisualStudio中的脚本 我的目标是能够编译程序,以 不修改引用定义的链接器的源代码 符号,但在VisualStudio中使用我自

我正在努力转换一个与gnu工具链的ld链接的C程序 使其作为visual studio(2005)项目编译。 程序将.data符号放在不同的段中,并在 初始化阶段它在段之间复制数据。指向 段的开始和结束在ld链接器脚本中定义

我了解如何将变量定位到不同的、用户定义的 段,但我还没有弄清楚如何定义链接器常量 例如"我的"段的"开始",或者是否有类似链接器的东西 VisualStudio中的脚本

我的目标是能够编译程序,以 不修改引用定义的链接器的源代码 符号,但在VisualStudio中使用我自己的自定义数据布局 项目

下面是一些示例C代码,说明了我想要什么 to do和一个(精简的,可能语法不正确的)版本 与gcc/ld链接时使用的make脚本

任何提示都将不胜感激

#pragma data_seg( "MY_DATA_FOO" )
#pragma data_seg( "MY_DATA_BAR" )
#pragma comment(linker, "/section:MY_DATA_BAR,R")

__declspec(allocate("MY_DATA_FOO")) int foo1;
__declspec(allocate("MY_DATA_FOO")) int foo2;

__declspec(allocate("MY_DATA_BAR")) int bar1 = 1;
__declspec(allocate("MY_DATA_BAR")) int bar2 = 2;

#pragma data_seg( )
void test() {
    foo1 = bar1;
    foo2 = bar2;

    // i would rather do this as 
    //extern unsigned int __start_of_MY_DATA_FOO;
    //extern unsigned int __start_of_MY_DATA_BAR;
    //extern unsigned int __size_of_MY_DATA_BAR;
    //memcpy(__start_of_MY_DATA_FOO, _start_of_MY_DATA_BAR, _size_of_MY_DATA_BAR);
}
伪链接脚本(Visual Studio的等效脚本是什么

MEMORY
{
  foo:  org=0x1000, len=0x100
  bar:  org=0x2000, len=0x100
}

SECTIONS
{
    GROUP:
    {
        MY_DATA_FOO : {}
        __start_of_MY_DATA_FOO = ADDR(MY_DATA_FOO);
        __end_of_MY_DATA_FOO = .;
        __size_of_MY_DATA_FOO = SIZEOF(MY_DATA_FOO);
    } > foo

    GROUP:
    {
        MY_DATA_BAR : {}
        __start_of_MY_DATA_BAR = ADDR(MY_DATA_BAR);
        __end_of_MY_DATA_BAR = .;
        __size_of_MY_DATA_BAR = SIZEOF(MY_DATA_BAR);
    } > bar
}

创建其他段(它们按字母顺序放置在内存中):


然后复制&fooFirst和&fooFirst之间的所有内容。

可以通过合并段来删除填充

比如说

#pragma data_seg(".foo_begin")
#pragma data_seg(".foo_data")
#pragma data_seg(".foo_end")

#pragma comment( linker, "/merge:.foo_begin=.foo" )
#pragma comment( linker, "/merge:.foo_data=.foo" )
#pragma comment( linker, "/merge:.foo_end=.foo" )

__declspec(allocate(".foo_begin")) int foo_begin_marker;
__declspec(allocate(".foo_end")) int foo_end_marker;

__declspec(allocate(".foo_data")) int foo_data;

这确实是不应该做的事情。当然也有一些可移植的方法来编写相同的程序。听起来好像有人认为他们聪明地愚弄了低级的构建链内部构件,而不是正确地使用C…这比假设在调用函数返回后可以从调用函数中访问局部变量要高出一步。..@R:使用此模式的理由很少,但偶尔也有正当的理由。我使用它来添加调试检查。在发布版本中,我的对象是独立的,彼此不了解。但对于调试,它们是独立的。“合法的C/C++”这个方法是一个中央寄存器来跟踪它,只是为了调试,实际上比这个方法要维护200多件事情(这个方法是自动的)。另一方面,可导入性是一种不同的成本。感谢您的建议。但是,当我尝试时,fooFirst的地址不小于wulFast,&foo1大于&wulFast。此外,似乎还有一些填充将段对齐到0x1000块。这可能由某些编译器和链接进行调整r-settings。关于您使用的设置有什么提示吗?再次感谢!我在#pragma init_seg(此处)的文档中找到了一个您建议的技巧示例。它说“节名必须小于等于8个字符。在$之前具有相同名称的节将合并到一个节中。它们合并的顺序是通过对$之后的字符进行排序来确定的。”并且,当我将节名更改为“MY_DATA_FOO$”时“等等,它们的排序结果是正确的。但是,每个节大小仍然是零填充的,大约为0x100字节,这使得很难知道段的“正确”结尾。下面是来自ATL源的一个示例:#pragma节(“ATL$u a”,read,shared)#pragma节(“ATL$u z”,read,shared)#pragma节(“ATL$u m”,read,shared)尝试使用section而不是data_seg。是的,它们都可以工作(如果在节名称中使用“$”)。但是两者都添加了一些填充,所以我仍然不知道如何构造_MY_data_BAR.hmm的符号uu size_。我也有一个对齐方式。这很奇怪。谢谢!但是,我仍然在变量之间有0x100字节的填充,(不是吗?)。如果没有merge命令,则填充为0x1000字节,并且段的顺序错误,因此merge命令确实有一些效果,并且似乎与其他方法(在节名中使用$)一样有用。
#pragma data_seg(".foo_begin")
#pragma data_seg(".foo_data")
#pragma data_seg(".foo_end")

#pragma comment( linker, "/merge:.foo_begin=.foo" )
#pragma comment( linker, "/merge:.foo_data=.foo" )
#pragma comment( linker, "/merge:.foo_end=.foo" )

__declspec(allocate(".foo_begin")) int foo_begin_marker;
__declspec(allocate(".foo_end")) int foo_end_marker;

__declspec(allocate(".foo_data")) int foo_data;