小编Sue*_*ode的帖子

算术右移给出虚假的结果?

我必须在这里绝对疯狂,但gcc 4.7.3在我的机器上给出了最荒谬的结果.这是我正在测试的确切代码:

#include <iostream>

using namespace std;

int main(){
  unsigned int b = 100000;
  cout << (b>>b) << endl;
  b = b >> b;
  cout << b << endl;
  b >>= b;
  cout << b << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,这是正确的本身转移任意数量应该导致0(n/(2^n) == 0整数除法,n>1正/无符号),但不知何故,这里是我的输出:

100000
100000
100000
Run Code Online (Sandbox Code Playgroud)

我疯了吗?可能会发生什么?

c++ gcc bit-shift undefined-behavior

30
推荐指数
2
解决办法
1641
查看次数

如何允许全局函数访问私有成员

如何允许全局功能访问私有成员?

限制是您不允许直接friend在类声明中使用全局函数.原因是因为我不希望用户必须在头文件中看到所有这些全局函数.函数本身在实现文件中定义,我希望尽可能地将它们隐藏在那里.

现在你可能想知道为什么我有这么多全局函数.为了简单起见,我正在使用windows注册各种WNDPROC函数作为回调,它们必须是全局的.此外,他们必须能够更新各种类别私有的信息.

我想出了两个解决方案,但两者都有点粘.

解决方案1.让所有需要后门的成员protected而不是private.在实现文件中,声明一个类转换器,它继承自原始类,但为受保护的成员提供公共getter.当您需要受保护的成员时,您可以简单地转换为更改者类:

//Device.h
class Device{
protected:
  std::map<int,int> somethingPrivate;
};

//Device.cpp
DeviceChanger : public Device{
private:
  DeviceChanger(){} //these are not allowed to actually be constructed
public:
  inline std::map<int,int>& getMap(){ return somethingPrivate; }
};

void foo(Device* pDevice){ ((DeviceChanger*)pDevice)->getMap(); }
Run Code Online (Sandbox Code Playgroud)

当然,继承此类的用户现在可以访问受保护的变量,但它允许我至少隐藏大多数重要的私有变量,因为它们可以保持私有.

这是有效的,因为DeviceChanger实例具有完全相同的内存结构Device,因此没有任何段错误.当然,这正在进入未定义的C++域,因为该假设依赖于编译器,但我关注的所有编译器(MSVC和GCC)都不会更改每个实例的内存占用,除非添加了新的成员变量.

解决方案2.在头文件中,声明一个朋友转换器类.在实现文件中,定义该友元类并使用它通过静态函数获取私有成员.

//Device.h
class DeviceChanger;
class Device{
  friend DeviceChanger;
private:
  std::map<int,int> somethingPrivate;
};

//Device.cpp
class DeviceChanger{
public:
  static inline std::map<int,int>& getMap(Device* pDevice){ return pDevice->somethingPrivate; }
};

void foo(Device* pDevice){ …
Run Code Online (Sandbox Code Playgroud)

c++

10
推荐指数
1
解决办法
4667
查看次数

随应用程序发送libstdc ++.so.6

我想在我的应用程序中使用gcc 4.8.1(需要libstdc ++.so.6.0.18),但是客户只有libstdc ++.so.6.0.13.我已经使用-static-libgcc -static-stdlibc++了一段时间,但我的应用程序包含几个动态链接库和一个主要应用程序.这意味着在编译每个动态库时,它们必须静态编译标准库,这是多余且浪费的.我想用我的产品运送我选择的标准库,但是每次我在像他们这样的环境中运行我的应用程序时,它总是加载错误的标准库./usr/lib64/无论我似乎做什么,它都喜欢这个版本(似乎优先考虑LD_LIBRARY_PATH).

约束:

  1. 我不允许强迫他们升级到新的标准库.

  2. 我不想让动态库保持静态.(我可以将所有内容静态编译到主应用程序中一次,但是有一些后勤障碍阻止我将某些库重新编译为静态库).

-Wl,-rpath=$(path_to_directory)有点危险,但它是合法的,因为客户确实采取了一些允许我设置路径变量的设置.但是,设置我的新stdlibc ++的rpath似乎并没有覆盖默认/usr/lib64版本.我仍然会收到GLIBCXX错误,因为它不会使用正确的库.

当然有一个优雅的解决方案吗?

也许我的程序中只有一个错误.这是一个例子(对于审查员抱歉,但它只是用户名的东西):

~/example$ pwd
/home/username/example
~/example$ echo $LD_LIBRARY_PATH

~/example$ ls
Makefile  libstdc++.so.6.0.18  test.cpp
~/example$ make
g++ -std=c++11 -Wall -Werror test.cpp -o test
~/example$ ldd test
./test: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./test)
    linux-vdso.so.1 =>  (0x00007fffe5919000)
    libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x000000390b800000)
    libm.so.6 => /lib64/libm.so.6 (0x0000003904800000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000390b400000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003904400000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003904000000)
~/example$ setenv LD_LIBRARY_PATH /home/username/example …
Run Code Online (Sandbox Code Playgroud)

c++ linker libstdc++

7
推荐指数
1
解决办法
1673
查看次数

Windows 7上的Kinect v2

所以我终于在邮件中获得了两个Kinect v2,并期待从他们那里获得一些原始数据,看看他们互相干扰了多少.我去下载SDK,由于某种原因我从未注意到Windows 8的要求......因为在Windows 7中不受支持.

这感觉很虚伪和不必要,但很好,我不能做任何事情.在我浪费一些钱将我的机器升级到我真正不想要的操作系统之前,有没有办法让Kinect v2与Windows 7机器(或者甚至是Ubuntu)通话?我不需要任何花哨的骨骼检测或任何东西; 我只想要原始xyz-rgb数据.我正在阅读关于OpenNI(以及他们新的Apple霸主)的内容,我希望通过一些奇迹,他们的最后一个开源发行版将与Kinect v2s向前兼容?

TL; DR:有没有可以在Windows 7-64bit上与Kinect v2连接的免费SDK?

kinect openkinect kinect-sdk

6
推荐指数
1
解决办法
2万
查看次数

使用 javaagents 在 Java 中进行基本块日志记录

我的目标是在一些 Java 字节码的每个基本块的开头插入少量代码。目的是通过基本块记录执行路径。目前,我正在使用 Javassist 在方法的开头和结尾处检测一些代码,但我在使用 Javassist API 检测更精细的字节码位置时遇到了困难。

Javassist 为我提供了一个 Block[],它表示方法中的所有基本块。基本块可以报告它们的字节码位置,因此我知道我的仪器需要去哪里。我想使用的 Javassist 工具是 CtMethod.insertAt(int sourceCodeLineNumber,String newSourceCode),但是这使用源代码行号而不是字节码行号,这会导致这个问题中说明的问题(我相当确定没有至此解决该问题)。

问题:当变量本身来自 Javassist 检测时,如何使用检测为方法内的变量赋值。我最好不必使用其他工具,但目前我正在寻求任何可以获得的帮助。

使用 Javassist 声明变量如下:

//m is a CtMethod           
try { m.addLocalVariable("someVar", ClassPool.getDefault().get("SomePackage.SomeClass")); } 
catch (NotFoundException e) { e.printStackTrace(); }
Run Code Online (Sandbox Code Playgroud)

我最坏的情况是以某种方式推断 javassist 检测的堆栈变量,并使用遍历整个方法/类的迭代器插入字节码,但这真的很糟糕。我的方法只有一个整数输入(块 ID)和 void 输出,因此 Java 字节码在每个基本块的开头看起来像这样:

ALOAD 6 //6 is my new Javassist variable ID, however I don't think I can get Javassist to actually tell it to me
ICONST_1 //My parameters, which is …
Run Code Online (Sandbox Code Playgroud)

java instrumentation javassist

5
推荐指数
1
解决办法
2081
查看次数

静态成员与静态全局

我已经读过全局变量和静态全局变量之间的区别在于全局变量可以通过extern在另一个实现文件中引用,而静态全局变量仅局限于该实现文件.看到这两个问题,以了解更多信息:[ 1,2 ].

据我了解,这是指下列foo()bar()应相同链接.这两个功能只能用于MyClass.

//MyClass.h
Class MyClass{
private:
  static void foo();
};

//MyClass.cpp
void MyClass::foo(){}
static void bar(){}
Run Code Online (Sandbox Code Playgroud)

我可以看到foo()声明更常见,因为它让头文件更完整地布局整个类(即使你不能/不应该使用私有的东西),但是不好的做法声明一个类似的函数bar()(隐藏自头文件)?

对于上下文,我定义了一个WNDPROC需要静态工作的Windows消息,但这是一个相当丑陋的声明,我不确定是否应该将它完全隐藏在实现文件中,或者继续在头文件中声明它.

c++ linker

4
推荐指数
1
解决办法
3610
查看次数

OpenCV的calcOpticalFlowPyrLK抛出异常

我一直试图用OpenCV形成一个小的光流示例.一切正常,除了函数调用calcOpticalFlowPyrLK,它在控制台窗口中打印以下失败的断言:

OpenCV错误:断言失败(mytype == typ0 ||(CV_MAT_CN(mytype)== CV_MAT_CV(type0)&&((1 << type0)&fixedDepthMask)!= 0))在未知函数中,文件......\src\opencv\modules\core\src\matrix.cpp,第1421行

我正在解析的视频分为300个图像,标记为"caml00000.jpeg","caml00001.jpeg",...,"caml00299.jpeg".这是我写的代码:

#include <cv.h>
#include "opencv2/highgui/highgui.hpp"

using namespace cv;
using namespace std;

int main( int argc, char** argv ){

    char buff[100];
    int numFrames=300;
    char fileFormat[]="images/caml%05d.jpeg";

    string winname="Test Window";

    vector<Mat> imgVec(numFrames);

    auto itrImg=begin(imgVec);
    auto itrEnd=end(imgVec);
    vector<Point2f> featuresPrevious;
    vector<Point2f> featuresCurrent;

    namedWindow( winname, CV_WINDOW_AUTOSIZE );
    int fileNum=0;
    while(itrImg!=itrEnd){
        Mat& imgRef=*itrImg; //get this frame's Mat from the vector iterator

        //Calculate the name of the file;
        sprintf(buff,fileFormat,fileNum);
        string fileName=buff;
        //string fileName="kitty.jpg"; //attempted using a static picture as …
Run Code Online (Sandbox Code Playgroud)

c++ opencv assertions opticalflow

3
推荐指数
1
解决办法
1万
查看次数

浮点舍入不正确

在gcc上4.7.3,我的fegetround()函数返回FE_TONEAREST.根据c ++参考,这意味着从零开始四舍五入.本质上,它意味着在乘法后调整尾数的精度时保存移出的最后一位(因为它将是它应该的两倍).然后,将保存的位添加到最终的尾数结果中.

例如,浮点乘法给出以下结果:

0x38b7aad5 * 0x38b7aad5 = 0x3203c5af
Run Code Online (Sandbox Code Playgroud)

乘法后的尾数是

  1011 0111 1010 1010 1101 0101
x 1011 0111 1010 1010 1101 0101
-------------------------------
1[000 0011 1100 0101 1010 1110] [1]000 0101 1001 0101 0011 1001
Run Code Online (Sandbox Code Playgroud)

[23'b]组保持有效数字,而该[1'b]组保持最后一位移出.请注意,结果的尾数是

[000 0011 1100 0101 1010 1111]
Run Code Online (Sandbox Code Playgroud)

最后一位切换到,1因为由于舍入模式,该[1'b1]组被添加到拼接的尾数([23'b]集合).

这是一个让我感到难过的例子,因为它让我觉得硬件没有正确地舍入.

0x20922800 * 0x20922800 = 0x1a6e34c (check this on your machine)

  1010 0110 1110 0011 0100 1101
x 1010 …
Run Code Online (Sandbox Code Playgroud)

c++ floating-point floating-accuracy floating-point-precision

3
推荐指数
1
解决办法
407
查看次数

使用decltype编写复制和移动函数

我的代码有几个实例,当遇到T &&或const T&时函数的反应略有不同,但是函数本身很长(注意T只是一些对象类型).例如:

void push_back(const T& newt){
    /* code block X */
    new (ptr) T(newt);
    /* code block Y */
}

void push_back(T&& newt){
    /* code block X */
    new (ptr) T(std::move(newt));
    /* code block Y */
}
Run Code Online (Sandbox Code Playgroud)

是否可以按照这个伪代码的方式写一些东西:

template<typename S>
void push_back(S newt){
    /* code block X */
#if decltype(newt)==T&&
    new (ptr) T(std::move(newt));
#else
    new (ptr) T(newt);
#endif
    /* code block Y */
}
Run Code Online (Sandbox Code Playgroud)

或者是否有更好的方法来编写几乎相同的移动和复制功能?

c++ templates decltype move-semantics c++11

2
推荐指数
1
解决办法
193
查看次数

在notepad.exe中挂钩CreateFile不会捕获API调用

我的最终目标是通过在kernel32.dll中挂钩文件api来跟踪explorer.exe完成的文件操作,但是我还没有完成它的工作(explorer.exe没有调用API,或者我的结果有问题).为了弄清楚发生了什么,我设定了一个目标来跟踪notepad.exe创建文件的时间,但是由于某种原因这也失败了!

我有3个Visual Studio 2012 C++项目:我的DLL,一个DLL注入器,它将强制任何可执行文件加载我的dll(虽然如果Unicode/Multibyte和32/64bit设置不匹配可能会失败),以及一个测试程序,调用API.我有一个批处理文件,它将启动我的测试程序,然后使用注入器程序将我的DLL加载到测试程序中.奇怪的是输出确实显示在测试程序上跟踪API(生成控制台并打印所有内容!)但是没有任何事情发生在notepad.exe(没有控制台=没有捕获操作).

这是挂钩API的DLL(使用mhook库).格式和概念取自指南.需要注意的重要事项是我挂起CreateFile(A/W),并在第一次操作发生时生成一个控制台来打印文件I/O日志.

#include "stdafx.h"
#include "mhook/mhook-lib/mhook.h"

//////////////////////////////////////////////////////////////////////////
// Defines and typedefs
typedef HANDLE (WINAPI *CreateFileWFP)(
    _In_ LPCWSTR lpFileName,
    _In_ DWORD dwDesiredAccess,
    _In_ DWORD dwShareMode,
    _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    _In_ DWORD dwCreationDisposition,
    _In_ DWORD dwFlagsAndAttributes,
    _In_opt_ HANDLE hTemplateFile
    );
typedef HANDLE (WINAPI *CreateFileAFP)(
    _In_ LPCSTR lpFileName,
    _In_ DWORD dwDesiredAccess,
    _In_ DWORD dwShareMode,
    _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    _In_ DWORD dwCreationDisposition,
    _In_ DWORD dwFlagsAndAttributes,
    _In_opt_ HANDLE hTemplateFile
    );

//////////////////////////////////////////////////////////////////////////
// Original function
CreateFileWFP OriginalCreateFileW = (CreateFileWFP)::GetProcAddress(::GetModuleHandle(TEXT("kernel32")), "CreateFileW"); …
Run Code Online (Sandbox Code Playgroud)

c++ dll hook winapi

2
推荐指数
1
解决办法
5691
查看次数

for always in always block

我有一个高速缓存存储器模块,我想要字可寻址,但有字节的写使能信号.

always @ (posedge clk) begin
    //stuff...
    if(write) begin
        //Word accessible only
        //memData[lastInIndex][lastInOffset] <= lastWriteData;

        //Supporting byte accessible
        if(lastWrEn[0])
            memData[lastInIndex][lastInOffset][7:0] <= lastWriteData[7:0];
        if(lastWrEn[1])
            memData[lastInIndex][lastInOffset][15:8] <= lastWriteData[15:8];
        if(lastWrEn[2])
            memData[lastInIndex][lastInOffset][23:16] <= lastWriteData[23:16];
        if(lastWrEn[3])
            memData[lastInIndex][lastInOffset][31:24] <= lastWriteData[31:24];
    end
    //more stuff...
end
Run Code Online (Sandbox Code Playgroud)

如果我正在向存储器写一个字,我可以指定应该忽略哪些字节以及应该在每个字中写入哪些字节.我已经测试了这段代码,它模拟得很好.我想参数化一个字中有多少字节(在64位情况下,现在每个字有8个字节).我希望有一些for循环来实例化我的逻辑,而不是仅仅复制和粘贴更几乎相同的行.

always @ (posedge clk) begin
    //stuff...
    if(write) begin
        //Word accessible only
        //memData[lastInIndex][lastInOffset] <= lastWriteData;

        //Supporting byte accessible
        begin : BYTE_SELECTION_GENERATE
            integer i;
            for(i=0; i<bytesPerWord; i=i+1)
                if(lastWrEn[i])
                    memData[lastInIndex][lastInOffset][i*8+7:i*8] <= lastWriteData[i*8+7:i*8];
        end
    end
    //more stuff...
end
Run Code Online (Sandbox Code Playgroud)

我有一个名为的参数wordSize,指定每个单词包含多少位(通常为32或64).还有另一个参数parameter bytesPerWord = wordSize/8 …

verilog

2
推荐指数
1
解决办法
9538
查看次数

C++调用错误签名的函数

我有一个带有这个api的头文件:

class XmlTree {
    public:
    template<typename T> void Set(const std::string& path, const T& val, const std::string& attrib = "") {...}
    template<typename T> void Set(const std::string& path, const T& val, bool encrypt) {...}
}
Run Code Online (Sandbox Code Playgroud)

代码正在执行此行:

static XmlTree get_root_response(const string& api_name, int code = 0) {
    XmlTree output;
    //api_name is a const string&="Wut", code is an int=200
    output.Set<int>("/" + api_name, code, "code"); //on this line
    ...
    return output;
}
Run Code Online (Sandbox Code Playgroud)

由于某种原因,这会调用第二个Set函数签名而不是第一个.GDB显示了这个:

#1 XmlTree::Set<int> (this=address, path="/Wut", val=@address: 200, encrypt=true)
#2 get_root_response(api_name="Wut", code=200)
Run Code Online (Sandbox Code Playgroud)

很明显,正在调用错误的函数签名,但我不知道它究竟是如何得到错误的bool输入.任何人都知道为什么会发生这种情况?

c++

2
推荐指数
1
解决办法
73
查看次数

创建is_primitive或is_inheritable模板

我想创建一个模板来检查类类型是否是原始类型(int,char,float,float***,ect ...).这样做的原因是为了防止另一个模板尝试扩展原语并导致编译时错误.到目前为止,我有以下几点:

#include <typeinfo>
template<typename T>
struct is_primitive{
   const static bool value=std::is_fundamental<T>::value;
};
Run Code Online (Sandbox Code Playgroud)

显然,这只是转发is_fundamental的结果.我想添加remove_pointer,remove_reference,ect ...来删除输入类的所有额外修饰符. 使T尽可能裸露所需的所有移除是什么?

或者,像下面这样的解决方案也同样出色:

template<typename T>
struct is_inheritable{
   const static bool value=???;
};
Run Code Online (Sandbox Code Playgroud)

但我很确定不可继承的类集等于原始类的集合.

c++ templates std c++11

1
推荐指数
1
解决办法
352
查看次数