这是一个非常简单的问题.请考虑以下代码:
#include <iostream>
#include <memory>
typedef std::unique_ptr<void> UniqueVoidPtr;
int main() {
UniqueVoidPtr p(new int);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用以下命令使用cygwin(g ++ 4.5.3)进行编译g++ -std=c++0x -o prog file.cpp就可以了.但是,使用Microsoft编译器(VS 2010或2013)进行编译时出现此错误:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\memory(2067) : error C2070: 'void': illegal sizeof operand
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\memory(2066) : while compiling class template member function 'void std::default_delete<_Ty>::operator ()(_Ty *) const'
with
[
_Ty=void
]
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\type_traits(650) : see reference to class template instantiation 'std::default_delete<_Ty>' being compiled
with
[ …Run Code Online (Sandbox Code Playgroud) 我工作的团队生成一个用于Python的共享库.这个库完全是C++,我们使用Boost来暴露给python.因为我们不能保证我们的客户端安装了Boost库,所以我们将Boost所需的功能静态地提供给共享对象文件.编译的最后阶段看起来很熟悉
g++ -o <output> <objects> -Wl,-Bstatic -lboost_python -lboost_regex ... -Wl,-Bdynamic -shared <other_opts>
Run Code Online (Sandbox Code Playgroud)
我们传统上使用自己构建的Boost:1.47.这个版本现在已经很老了,所以我们希望更新.但奇怪的是,当我在CentOS 7系统上使用yum安装必要的对象时,我从gcc中收到以下错误:
relocation R_X86_64_32 against '.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
Run Code Online (Sandbox Code Playgroud)
好吧,我以为我只需要下载最新版本(CentOS 7安装Boost 1.53)并自行构建.毕竟,这一直对我们有用.我按照这里的说明,但我得到了同样的错误.如何强制使用-fPIC来构建它构建的静态库?
从Windows中生成子流程获取返回值的方法是什么?它看起来ShellExecute()比使用起来更简单CreateProcess(),但是从我到目前为止所做的阅读中,都没有说明如何检查衍生过程的返回值.怎么做的?
谢谢,安迪
我需要围绕一个硬件进行进程间同步.因为这段代码需要在Windows和Linux上运行,所以我使用Boost Interprocess互斥锁.一切正常,请接受我检查放弃互斥锁的方法.这种情况有可能发生,所以我必须做好准备.
我在测试中放弃了互斥锁,当然,当我使用scoped_lock来锁定互斥锁时,进程会无限期地阻塞.我想通过在scoped_lock上使用超时机制来解决这个问题(因为Googling花费了大量时间来解决这个问题并没有真正显示出来,因为可移植性原因,提升并没有做太多事情).
不用多说,这就是我所拥有的:
#include <boost/interprocess/sync/named_recursive_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
typedef boost::interprocess::named_recursive_mutex MyMutex;
typedef boost::interprocess::scoped_lock<MyMutex> ScopedLock;
MyMutex* pGate = reinterpret_cast<MyMutex*>(new MyMutex(boost::interprocess::open_or_create, "MutexName");
{
// ScopedLock lock(*pGate); // this blocks indefinitely
boost::posix_time::ptime timeout(boost::posix_time::microsec_clock::local_time() + boost::posix_time::seconds(10));
ScopedLock lock(*pGate, timeout); // a 10 second timeout that returns immediately if the mutex is abandoned ?????
if(!lock.owns()) {
delete pGate;
boost::interprocess::named_recursive_mutex::remove("MutexName");
pGate = reinterpret_cast<MyMutex*>(new MyMutex(boost::interprocess::open_or_create, "MutexName");
}
}
Run Code Online (Sandbox Code Playgroud)
这至少就是这个想法.三个有趣的观点:
那么,我在使用这些对象时缺少什么?也许它正盯着我看,但我看不到它,所以我在寻求帮助.
我还应该提一下,由于这个硬件的工作方式,如果进程无法在10秒内获得互斥锁的所有权,则互斥量将被放弃.事实上,我可能只需要等待50或60毫秒,但10秒是一个很好的"圆"数量的慷慨.
我正在使用Visual Studio 2010在Windows 7上进行编译. …
我有一个第三方C库,其导出方法之一如下:
#define MAX_INDEX 8
int GetStuff(IN char* index[MAX_INDEX], OUT char* buf, IN size_t size);
Run Code Online (Sandbox Code Playgroud)
第一个参数填充了指向存储特定字符串的buf参数的指针.大小表示每个字符串在buf缓冲区中的预期长度.我的C#P/Invoke方法目前看起来像这样:
[DllImport("Path/To/Dll", CharSet = CharSet.Ansi)]
private static extern int GetStuff(IntPtr indecies, IntPtr buf, Int32 size);
Run Code Online (Sandbox Code Playgroud)
C#P/Invoke方法是私有的,因为我将它的功能包装在一个公共的"getter"方法中,该方法处理调用者的内存分配/释放.当我在C++中使用这个方法时,迭代实际上非常简单.我只是做了类似的事情:
char* pIndecies[MAX_INDEX];
char* pBuffer = new char[MAX_INDEX * (256 + 1)]; // +1 for terminating NULL
GetStuff(pIndecies, pBuffer, 256);
// iterate over the items
for(int i(0); i < MAX_INDEX; i++) {
if(pIndecies[i]) {
std::cout << "String for index: " << i << " " << pIndecies[i] << std::endl;
}
} …Run Code Online (Sandbox Code Playgroud) 我有一些代码,我正在尝试创建一个共享内存段.为此,该段由一个类内部进行管理.共享段将以"公告板"的方式使用.也就是说,这一个进程将写入它,许多其他进程将从中读取.无需再费周折:
#include <string>
#include <sys/types.h>
#include <boost/interprocess/managed_shared_memory.hpp>
static const std::string SHM_NAME("SharedMemory");
static const std::string SHM_STATUS("StatusArray");
static const std::string SHM_INFO1("MfgData");
class Manager {
u_int8_t* _status;
char* _info;
boost::interprocess::managed_shared_memory _shm;
Manager()
: _shm(boost::interprocess::create_only, SHM_NAME.c_str(), 1024)
{
// the process goes out to lunch on this first call, it's like a deadlock
status = _shm.construct<u_int8_t>(SHM_STATUS.c_str()) [128] (0); // array 128 bytes, init to 0
info = _shm.construct<char>(SHM_INFO1.c_str()) [256] (0);
}
public:
~Manager() {
_shm.destroy<u_int8_t>(SHM_STATUS.c_str());
_shm.destroy<char>(SHM_INFO1.c_str());
boost::interprocess::managed_shared_memory_object::remove(SHM_NAME.c_str());
}
Manager* Builder() {
// just in …Run Code Online (Sandbox Code Playgroud) 我知道如何使用Setup API来启用和禁用设备.我需要知道的是,我可以使用相同的API来确定设备是否已启用/禁用?我认为真正的问题是如何使用它因为Microsoft的devcon使用Setup API来操作硬件,该程序将告诉您设备是启用还是禁用(与设备管理器一样).这是怎么做到的?到目前为止,我对Setup API方法的研究并没有给出明确的答案.
安迪
我不会说我完全理解 const 正确性的想法,但至少可以说我理解它。所以,当我遇到这个问题时,我被难住了。有人可以向我解释一下吗?考虑以下代码:
\n\n#include <iostream>\n\nstruct Test {\n int someInt;\n void * pSomething;\n};\n\nvoid TestFunc(Test * const pStruct) {\n pStruct->someInt = 44;\n pStruct->pSomething = "This is a test string"; // compiler error here\n}\n\nint main() {\n Test t;\n TestFunc(&t);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n在我用注释进行注释时,我从 gcc (4.5.3 for cygwin) 收到此错误:
\n\nfoo.cpp:10:24: error: invalid conversion from `const void*\' to `void*\'\nRun Code Online (Sandbox Code Playgroud)\n\n这显然与结构包含 void* 这一事实有关,因为一些实验表明将结构更改为:
\n\nstruct Test {\n int someInt;\n char * pSomething;\n};\nRun Code Online (Sandbox Code Playgroud)\n\n产生警告而不是错误。此外,保持结构不变但修改此行以包含以下强制转换会编译代码而不发出警告:
\n\npStruct->pSomething = (void*)"This is a test …Run Code Online (Sandbox Code Playgroud) 我有一些作为 RPM 分发的软件项目。它们使用语义版本控制进行版本控制,我们在其上附加了一个版本号。使用常规约定,这是MAJOR.MINOR.PATCH-REL_NUM。尽管超出了本文的范围,但版本号存储在 git 中。在公布目标的makefile看起来是这样的:
release:
make clean
$(BLD_ROOT)/tools/incr_rel_num
# Although the third step, this was re-ordered to step 1
$(eval RELEASE_NUMBER=$(shell cat $(BLD_ROOT)/path/to/rel_num.txt))
make rpm RPM_RELEASE_NUM=$(RELEASE_NUMBER)
Run Code Online (Sandbox Code Playgroud)
在调试时,我最终发现,虽然调用eval是配方中的第三步,但它实际上是首先被评估的!这就是为什么 RPM 的版本号总是比我看到的推送到遥控器的版本号少。
我在这方面做了很多谷歌搜索,但我没有找到任何解释在食谱中使用eval时的评估顺序的命中。也许它甚至不是关于eval而是一般的功能。此外,我也没有在 make 的 GNU 手册中找到有关这方面的详细说明(如果有的话,请指出是哪一章)。我已经解决了这个问题,所以它不是一个麻烦,我只是想知道,这是预期的,如果是,为什么?
今天,我在Linux内核(include/linux/kernel.h)中遇到了这个宏
#define DIV_ROUND_CLOSEST(x, divisor)( \
{ \
typeof(x) __x = x; \
typeof(divisor) __d = divisor; \
(((typeof(x))-1) > 0 || /* <-- why does this work */ \
((typeof(divisor))-1) > 0 || (__x) > 0) ? \
(((__x) + ((__d) / 2)) / (__d)) : \
(((__x) - ((__d) / 2)) / (__d)); \
} \
)
Run Code Online (Sandbox Code Playgroud)
现在,我了解了宏的用途,并且以某种方式利用了“语句表达式”(下面的链接对此进行了提及)。我不明白的是((typeof(x))-1) > 0什么有用。从gcc文档中的此链接,我想我了解该typeof扩展名的含义。但是知道这一点似乎并不能回答在此宏中如何使用它。从我自己的实验,(typeof(x)-1)似乎不评价比其他任何东西-1,因此不这样始终会是小于 0(即假为三元的前两个部分)?
如果已经回答了这个问题,请指出。我确实进行了搜索,但是我的尝试没有返回特定于此用法的结果。
我有一个库项目,我正在移植到使用Linux中的autotools套件.我对autotools很新(本周).我已经学会了它的操作基础知识.我有一个关于如何保持内容config.h不被重新定义的问题.
我很惊讶地发现生成的config.h文件也没有,1)将每个宏包装在#ifndefor中,2)整个文件没有包装在标准中#ifndef CONFIG_H.
正如我所提到的,这段代码是基于Windows和Linux构建的.因此,宏的一些用途_linux(我不是说这是最好的名称,但它在各处都在使用)将元素引入仅存在于Linux中的类.因此,这将发生
header.h
#ifndef HEADER1_H
#define HEADER1_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif
Run Code Online (Sandbox Code Playgroud)
source.cxx
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "header.h" // oops, preprocessor gets excited because of redefs
Run Code Online (Sandbox Code Playgroud)
一个简单的解决方案是在config.h.in生成文件后执行标准的独特包装.但是,我想知道,有没有更好的方法来处理这个?我不可能是第一个遇到这种情况,甚至可能有一种处理它的方法,configure.ac但在这方面是一个完整的新手,我不知道甚至要搜索什么.
我正在尝试使用devcon.exe来检查各种硬件的状态.在示例中,我正在尝试检查我的SATA HBA状态,但是devcon正在抱怨它.这是代码:
int main(int argc, char** argv) {
std::string cmdLine("\"C:\\Users\\afalanga\\Documents\\Visual Studio 2010\\Projects\\PlayGround\\Debug\\devcon.exe\" status PCI\\VEN_8086^&DEV_3A22^&SUBSYS_75201462^&REV_00");
char* pCmdLine(new char[cmdLine.length() + 10]);
memset(pCmdLine, 0, cmdLine.length() + 10);
for(int i(0); i < cmdLine.length(); i++)
pCmdLine[i] = cmdLine.at(i);
STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi = {0};
if(!CreateProcess(NULL, pCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
std::cout << "Create child process failed. Error code: "
<< GetLastError() << std::endl;
return 1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
问题是,当上面执行时,devcon抱怨说"找不到匹配的设备".但是,如果我将该命令行从调试器复制/粘贴到我的命令提示符并按Enter键(或者当然删除调试器围绕它的所有包含引号),该命令将按预期完美地执行.
我在处理字符串时遇到了什么问题?以上是在MSDN上读取CreateProcess()文档的结果(发现不一定需要第一个参数,而cmd args根本不应该去那里).我分配10个额外字节的内存来复制字符串的原因是,在CreateProcess()函数的内部可能会改变"无论什么",而不会踩到其他内存.至少,当我这样做时,这是我的想法.