我有一个应用程序,它被分解为几个库,用于代码重用.在Windows上,我所要做的就是将.dll文件放在与可执行文件相同的路径中,它会自动找到它们.在Linux上(因为它硬编码事物的路径)我必须指定环境变量LD_LIBRARY_PATH或在可执行文件之前预加载库.
我已经看到了一些关于使用链接器选项嵌入路径的事情,-Wl,-rpath=<PATH>并且我已经尝试使用它.作为路径.但这只是查看当前的工作目录,而不是可执行文件的目录.
有没有办法在链接器中指定默认情况下查找共享库的可执行文件目录(如在Windows上)?
谢谢!马特
我正在尝试根据SQL 2005中的条件结果填充临时表.临时表将具有相同的结构,但将根据条件使用不同的查询填充.下面的简化示例脚本在ELSE块的语法检查中失败,INSERT INTO错误为:
数据库中已经有一个名为"#MyTestTable"的对象.
DECLARE @Id int
SET @Id = 1
IF OBJECT_ID('tempdb..#MyTestTable') IS NOT NULL DROP TABLE #MyTestTable
IF (@Id = 2) BEGIN
SELECT 'ABC' AS Letters
INTO #MyTestTable;
END ELSE BEGIN
SELECT 'XYZ' AS Letters
INTO #MyTestTable;
END
Run Code Online (Sandbox Code Playgroud)
我可以在IF/ELSE语句之前创建临时表,然后只INSERT SELECT在条件块中执行语句,但是表会有很多列,我试图提高效率.这是唯一的选择吗?或者有一些方法可以使这项工作?
谢谢,马特
我在使用Open-MPI 1.3.3的集群上使用CentOS 5.4 x86_64和Boost 1.42.0.我正在编写一个共享库,它使用共享内存来存储大量数据,供多个进程使用.还有一个加载器应用程序,它将读取文件中的数据并将它们加载到共享内存中.
当我运行加载器应用程序时,它确定了准确存储数据所需的内存量,然后增加了25%的开销.对于几乎每个文件,它将超过2演出数据.当我使用Boost的Interprocess库发出内存请求时,它表示它已成功保留了所请求的内存量.但是当我使用start开始使用它时,我得到一个"总线错误".据我所知,总线错误是访问内存段可用范围之外的内存的结果.
所以我开始研究如何在Linux上共享内存以及检查什么以确保我的系统配置正确以允许大量共享内存.
/proc/sys/kernel/shm*:
shmall - 4294967296(4 Gb)shmmax - 68719476736(68 Gb)shmmni - 4096ipcs -lm命令:
------ Shared Memory Limits -------- max number of segments = 4096 max seg size (kbytes) = 67108864 max total shared memory (kbytes) = 17179869184 min seg size (bytes) = 1
据我所知,这些设置表明我应该能够为我的目的分配足够的共享内存.所以我创建了一个在共享内存中创建大量数据的精简程序:
#include <iostream>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/vector.hpp>
namespace bip = boost::interprocess;
typedef bip::managed_shared_memory::segment_manager segment_manager_t;
typedef bip::allocator<long, segment_manager_t> long_allocator;
typedef bip::vector<long, long_allocator> long_vector;
int …Run Code Online (Sandbox Code Playgroud) 注意:这篇文章代表我的询问问题#1.在两个问题中重复引入块(直到达到数字的所有文本),因为它是回答问题可能需要的背景信息.
我有一个非托管C++库,它包含几个"更高级别"库之间共享和共享的类和函数.我现在需要提供对C#/ .Net应用程序的公共库的访问.为此,我将使用C++/CLI包装类包装公共库.
公共库中包含的类可以是包含嵌套类定义和成员变量的复杂类,这些变量是其他类对象的集合.集合变量是用于管理集合的自定义列表类的typedef的实例.公共库还包括表示使用FLEX/BISON创建的自定义脚本文件语法的已解析结构的类.公共库和"更高级别"库都是以允许跨平台(Linux和GCC)编译和使用的方式编写的.我所做的任何改变都必须允许这样做.
C++/CLI包装器类首先只需要读取功能.但随着项目的进展,我最终还需要能够创建和修改对象.
我了解C++/CLI并为其他非托管C/C++项目创建了几个包装器,并为这个公共库提供了抽象功能.所以我已经掌握了基础知识(以及一些高级知识).
我有两个与执行此任务相关的问题,因为他们可以产生自己的讨论和解决方案,我将我的问题分成不同的帖子.我将在每篇文章中包含指向其他问题的链接.
如何在项目中构建我的文件?
非托管和C++/CLI项目之间的名称空间和类名称不会发生冲突.由于非托管项目使用类名称的"C"前缀而C++/CLI不使用.所以非托管类CWidget将变得公正Widget.他们使用不同的根命名空间名称.
当涉及文件名时会出现问题.作为我的默认命名模式是使用Widget.h与Widget.cpp两个非托管C++/CLI.
目前正在设置项目,项目的所有文件都位于项目文件夹的根目录中.头文件的包含仅作为标题的名称(例如#include "Widget.h").并且为了适当地解析包含不同项目的文件,将另一个项目的路径添加到Additional Include Directories使用项目的属性中.
如果我将我的Additional Include Directories属性更改为解决方案的根(..\)并为非托管标头执行我的包含,那么#include "Unmanaged\Widget.h我有一个新问题,即解析非托管标头中包含的标头.因此,使用该选项需要将所有 include语句更改为其项目目录的前缀.我知道其他项目
重复文件名问题最明显/最快的解决方案是更改其中一个库的命名模式.因此对于C++/CLI项目,而不是使用Widget.h和Widget.cpp前缀或后缀m(托管)或w(包装).所以C++/CLI的文件将是mWidget.h,wWidget.h,WidgetM.h,或WidgetW.h.然后,我可以重复我现有的模式并保持良好状态.
但有没有更好的方法来组织文件,以便我可以保留我的前/后缀较少的文件名,只需对现有代码进行最小的更改?
我有一个跨平台的C++应用程序,它被分成几个共享库并从插件共享库中加载其他功能.插件库应该是自包含的,并且在不知道或不依赖于调用应用程序的情况下自行运行.
其中一个插件包含来自主应用程序的复制代码,因此包含与引擎中的代码名称重复的符号名称.(是的,我知道这通常是禁止的,但在插件编写时,引擎是单片二进制文件,无法共享库.)在Windows上,一切运行正常.在Linux上我们得到了段错误.通过查看错误的堆栈跟踪,在调用重复类名中的函数时,它在插件中发生.它似乎是由于引擎和插件具有略微不同版本的共享代码(某些类功能在插件中被注释掉).就好像插件将它的符号运行时链接到引擎而不是它自己.我们通过改变dlopen参数来"修复"这个问题dlopen(pFilepath, RTLD_LAZY | RTLD_LOCAL).
但是当我们重写引擎被拆分为共享库时(为了最终在插件中重用),我们再次得到了段错误.看看堆栈跟踪,它来自引擎 - >插件 - >引擎.
有没有办法指定运行时链接器不将插件的符号映射到引擎(特别是如果它们在插件中定义)?
谢谢!马特
我首先尝试将插件的代码包装在它自己的命名空间中.这不起作用,因为它静态链接到也链接到引擎的库.静态库的版本不同,所以段错误!
然后我改变了引擎的构建,它的库是静态链接的.当我运行它时,我不再有问题.因此,它似乎是导出共享库符号然后在打开时动态重定位到插件中的结果.但是当所有引擎的代码都在一个可执行文件中时,它不会导出其符号(因此它不会尝试将插件的符号重定位到引擎中).
我仍然有一个问题,因为有一个并行版本的程序(使用Open-MPI),仍然会得到段错误.它似乎仍在导出引擎的符号并重新定位插件.这可能与Open-MPI如何执行应用程序有关.
是否有任何链接器标志可以在插件共享库上使用,它会告诉它不要在运行时动态重定位符号?或者隐藏它的符号,以便它们不被重新定位?我试过-s("省略所有符号信息"),但显然没有改变动态符号(使用检查nm -D <plugin>).
我在本地模式下使用Visual Studio 2008中的ReportViewer控件,其中对象作为数据源.我的类映射到数据库中的数据表.在对象中,它根据需要加载相关对象.因此,在您尝试使用该属性之前,它会将引用保留为null,然后它会尝试自动从数据库加载它.这些类使用System.Data.SqlClient命名空间.
当我与Windows窗体应用程序中的对象进行交互时,一切都按预期工作.但是,当我传递要用作报表数据源的对象并尝试自动加载相关对象时,它会失败.代码创建一个SqlConnection对象,当我在其上调用GetCommand()时,抛出以下异常:
[System.Security.SecurityException] {
"Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed."
} System.Security.SecurityException
Run Code Online (Sandbox Code Playgroud)
我已经尝试搜索错误,但显示的所有结果都是在SQL Server或ASP.Net上运行的CLR程序集.我在创建SqlConnection对象之前尝试在我的代码中添加以下调用(如搜索结果中所示),但它显然没有做任何事情:
System.Data.SqlClient.SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted).Assert();
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
有谁知道从.Net应用程序监视SQL Server(2005或2008)数据库中的表记录更改的方法?它需要能够一次支持多个客户端.每个客户端在启动时都会"订阅",并在退出时"取消订阅".多个用户可以立即访问系统,我想在其他用户客户端上反映他们的更改.然后,当客户端处理更改事件时,它可以更新它表示该记录的本地对象.类似于修改的Access更新记录的方式反映在引用它的每个表单中.
我知道microsoft有他们的Microsoft.SqlServer库用于与SQL Server交互.但我不确定哪个概念适用于我想做的事情(或者可以弯曲以适用于我想做的事情).听起来可能有用的是管理者或复制者.
期待有人问,"你为什么不偶尔重新询问桌子以寻找新的信息?" 我有大量的桌子需要监控,这对屁股很痛苦.此外,如果我正在寻找更优雅的东西.
我愿意接受建议......
注意:这篇文章代表我的询问问题#2.在两个问题中重复引入块(直到达到数字的所有文本),因为它是回答问题可能需要的背景信息.
我有一个非托管C++库,它包含几个"更高级别"库之间共享和共享的类和函数.我现在需要提供对C#/ .Net应用程序的公共库的访问.为此,我将使用C++/CLI包装类包装公共库.
公共库中包含的类可以是包含嵌套类定义和成员变量的复杂类,这些变量是其他类对象的集合.集合变量是用于管理集合的自定义列表类的typedef的实例.公共库还包括表示使用FLEX/BISON创建的自定义脚本文件语法的已解析结构的类.公共库和"更高级别"库都是以允许跨平台(Linux和GCC)编译和使用的方式编写的.我所做的任何改变都必须允许这样做.
C++/CLI包装器类首先只需要读取功能.但随着项目的进展,我最终还需要能够创建和修改对象.
我了解C++/CLI并为其他非托管C/C++项目创建了几个包装器,并为这个公共库提供了抽象功能.所以我已经掌握了基础知识(以及一些高级知识).
我有两个与执行此任务相关的问题,因为他们可以产生自己的讨论和解决方案,我将我的问题分成不同的帖子.我将在每篇文章中包含指向其他问题的链接.
如何在非托管类中有效地包装/处理集合变量?
集合对象是自定义模板列表class(CObjectList<T>)的typedef,用于处理对象指针集合的管理.集合类提供所有基本集合功能以及指针管理和解构时对象的清理/释放.因此,代码中CWidget会有一个typedef CObjectList<CWidget> CWidgetList;.
代码和集合类模板参数中使用的大多数类都是类本身.但在某些情况下,该集合属于基类.这发生在自定义脚本FLEX/BISON解析器的已解析结构中.例如,有一个CCommand类可以继承所有其他可用命令.所以会有CSetCommand,CPrintCommand,CIfCommand,等.
我想为了做到这一点,我将不得不创建我的集合包装类,它维护非托管和C++/CLI类的单独列表.内部集合对象将管理非托管对象,并且必须有托管集合/列表对象来存储项目的包装类.
有没有人有任何关于如何做到这一点的例子/建议?或者如何编写可以将非托管类和C++/CLI类类型作为参数的泛型类?
对于具有标识字段的多个表,我们在这些视图上使用视图和替代触发器实现行级安全性方案.这是一个简化的示例结构:
-- Table
CREATE TABLE tblItem (
ItemId int identity(1,1) primary key,
Name varchar(20)
)
go
-- View
CREATE VIEW vwItem
AS
SELECT *
FROM tblItem
-- RLS Filtering Condition
go
-- Instead Of Insert Trigger
CREATE TRIGGER IO_vwItem_Insert ON vwItem
INSTEAD OF INSERT
AS BEGIN
-- RLS Security Checks on inserted Table
-- Insert Records Into Table
INSERT INTO tblItem (Name)
SELECT Name
FROM inserted;
END
go
Run Code Online (Sandbox Code Playgroud)
如果我想插入记录并获取其身份,在实现RLS而不是触发器之前,我使用了:
DECLARE @ItemId int;
INSERT INTO tblItem (Name)
VALUES ('MyName');
SELECT @ItemId …Run Code Online (Sandbox Code Playgroud) .net ×3
c++ ×3
c++-cli ×2
gcc ×2
linker ×2
linux ×2
sql ×2
sql-server ×2
visual-c++ ×2
wrapper ×2
boost ×1
c# ×1
collections ×1
database ×1
identity ×1
insert-into ×1
monitoring ×1
runtime ×1
sqlclient ×1
t-sql ×1
temp-tables ×1
triggers ×1
winforms ×1