小编Jam*_*ton的帖子

Cygwin的好选择? - Cygwin不支持原生支持Win32应用程序

更新2014年9月9日:TL; DR版本: 转到本文的底部,了解Cygwin如何调用非Cygwin程序.

在花了一些时间制作一些碰巧具有相当大规模的bash脚本之后,Cygwin的新版本已经破坏了它们.这些脚本调用本机Win32应用程序,这些应用程序不与Cygwin链接,Cygwin显然没有得到Cygwin的正式支持.

这让我感到惊讶,因为多年来我认为Cygwin可以在更复杂的环境中使用,该环境结合了原生的非Cygwin Win32应用程序和使用Cygwin兼容层的POSIX程序.但显然只支持POSIX兼容层,如果本机Win32非Cygwin应用程序工作,那么它被认为是一个愉快的巧合.

我从与Cygwin中针对.NET Framework编译的运行程序遇到的不兼容性中发现了这一点.这曾经很好,但几个月前被打破了.具体来说,通过管道传输到任何其他Win32程序的标准输入的.NET程序的标准输出通常会导致接收Win32程序获得过早的文件结束信号,因为几个月前Cygwin最近从字节管切换到消息管道 - 并且消息管道似乎与使用Visual C++或.NET Framework的任何接收应用程序不兼容.这是因为.NET向标准输出发出空写,只有在使用消息管道时才会将其传递给接收应用程序.接收应用程序成功读取零字节,因此认为它是文件结束.项目负责人似乎并不认为这是一个真正的问题,因为他们显然不支持从Cygwin中运行非Cygwin程序(惊喜!).

引用项目负责人Christopher Faylor从邮件列表中的多封电子邮件中引用:

你所看到的可能是因为Cygwin在几次修改之前被改为使用消息类型的管道.这不会改变.采用这种改变来解决Cygwin程序的问题,这显然是我们的首要任务.

无论有多少人使用Visual C++或.NET,他们都不是我们的目标受众.当事情适用于不想使用UNIX工具但不是我们主要关注点的人时,这很好.为那些想要使用非Cygwin东西的人修复问题并不是我认为非常重要的事情.

来自pipe.cc:请注意,管道的写入侧打开为PIPE_TYPE_MESSAGE.这似乎更接近于模仿Linux管道行为,并且pty处理肯定是必需的,因为fhandler_pty_master以块的形式写入管道,当指定CANON模式时由换行符终止.

以上评论在此处显示"和"关系.消息类型管道更接近模仿Linux(UNIX)管道行为,并且绝对是ptys所必需的.

我同意詹姆斯的说法,运行时可能是错误的但是我也同意cygwin应该能够处理这些情况.

您之间的完全协议不会产生太大影响.Cygwin源代码不会通过投票改变.

即使这个问题最终以某种方式得到解决 - 谁知道 - 他们可能在3个月内打破别的东西而不关心修复回归.他们可能会考虑一个补丁,但我需要花一些时间才能找到有用的东西.我认为我的时间更好地花在其他地方,因为很明显他们非常愿意破坏与原生Win32应用程序的兼容性,并且不想浪费更多时间让Win32应用程序工作.所以我猜Cygwin不应该被认为是混合Win32/Cygwin环境的稳定平台 - 我的替代方案是什么?我应该从哪里开始,以避免完全重写为bash以外的东西?我不使用超过基础Cygwin安装+一些基本的perl脚本.

更新: 在发布这个原始问题之后,他们最终pipe_byteCYGWIN环境变量中做了一个新标志:查看文档.如果设置了此标志,它将解决上面讨论的问题.调用非Cygwin Win32程序时,请务必确保pipe_byte已设置该标志.

但是,我发现了与.NET Framework 4.0和Cygwin不兼容的问题.以前版本的.NET Framework没有此问题.我在Cygwin邮件列表上首先提到了这个问题:

管道同步和Cygwin与.NET Framework 4.0之间的不兼容性

没有得到富有成果的回应,我进一步调查并发现Cygwin正在创建重叠管道,这会导致问题.请注意,尝试使用具有重叠管道的非重叠Win32 API调用是未定义的,并且大多数(所有?)Win32非Cygwin程序不使用重叠I/O及其标准文件句柄.我提交了一个补丁,它pipe_nooverlapCYGWIN环境变量中创建了一个标志,可以防止这种情况发生:

修补程序可选择禁用重叠管道

不幸的是,他们已经拒绝了补丁,所以你永远不会在主要的Cygwin DLL中看到这个:

Re:Patch可选择禁用重叠管道

拒绝补丁的原因:

  1. 暗示我打破了Cygwin中的信号实现; 我没有发现这种情况,因为信号仍然使用重叠管道.
  2. 他们不想添加环境变量标志,即使它显然是修复问题.
  3. 他们不想支持甚至可以选择具有非重叠管道的代码.

有了这样的推理和态度,我恐怕无法想办法改变贴片以满足他们的要求......他们似乎决定禁止使用不重叠的管道.我一直在使用补丁一段时间,并没有遇到任何问题.此外,我想不出pipe_nooverlap旗帜会破坏的任何情况(请参阅我的邮件列表中的后续电子邮件),但我将其留作旗帜以防万一有麻烦.

因此,如果要从Cygwin调用非Cygwin Win32或.NET Framework程序,则需要执行以下操作:

  1. 将我的补丁应用于您正在使用的Cygwin版本的源代码.不要指望这个补丁会在未来的Cygwin版本中出现.
  2. 在环境变量中设置pipe_bytepipe_nooverlap标志CYGWIN.

这工作......现在!!! 我发布这个以防万一其他人仍然想要使用Cygwin做某些事情.

windows bash cygwin

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

如何将Qt运行时DLL复制到项目输出

我有一个在Qt Creator中创建的简单项目(使用Qt SDK 1.1.4安装).它在Qt Creator中运行得很好,但如果我然后浏览到Windows中的输出目录并双击EXE,我将收到如下错误:

The program can't start because QtCored4.dll is missing from your computer.
Try reinstalling the program to fix this problem.
Run Code Online (Sandbox Code Playgroud)

这显然是因为Qt不在我的PATH中(我不希望它,如果我的计算机上有多个版本的Qt),Qt Creator/qmake没有将Qt DLL复制到项目输出.

我想要做的是使用qmake将必要的Qt文件复制到项目输出目录 - 无论它在哪里.我该怎么做呢?

(我尝试在qmake中创建一个自定义目标,但我不会太过分......)

更新2016年7月19日: 为了澄清,上述帖子涉及Qt4.在Qt5上,你应该考虑调用windeployqt.此Qt5工具将读取您的二进制文件,确定您需要哪些Qt5运行时文件,并将它们复制到二进制目录.另请注意,它将修复Qt5 :: Core库中特定于PC的绝对路径 - 因此,除非您想自己提供qt.conf文件,否则使用此工具基本上是强制性的.

c++ qt qmake qt4 qt-creator

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

使用EnumFontFamiliesEx函数枚举时字体太多

我正在尝试创建一个字体列表供用户选择.我这样做是通过使用该EnumFontFamiliesEx函数但不幸的是,返回的字体列表太长了.有许多额外的字体看起来轻浮,重复,用于不同的语言,或者不希望向用户显示.我的截图最能说明我试图过滤掉的垃圾.

我的调用代码EnumFontFamiliesEx如下所示:

LOGFONT lf;
memset(&lf, 0, sizeof(lf));
lf.lfCharSet = DEFAULT_CHARSET;
// screenDC is result of CreateCompatibleDC(NULL)
EnumFontFamiliesEx(screenDC, &lf, GetFontsCallback, NULL, 0);
Run Code Online (Sandbox Code Playgroud)

在按字母顺序排序并删除具有重复面部名称的字体后,生成的列表如下所示:

在此输入图像描述

正如您所看到的,ChooseFont字体常用对话框显示了一个非常合理的字体列表,这些字体用户友好且有意义.另一方面,我的代码显示了一长串额外字体:以"@"开头的字体(为什么?它们甚至用于什么?),3种额外的Arial字体变体,以及其他一些未知用途的字体,如Aheroni, Andalus,Angsana New,AngsanaUPC等.这太疯狂了.

如何过滤返回的字体列表EnumFontFamiliesEx,使其与对话框中显示的列表完全匹配ChooseFont

c c++ windows winapi fonts

25
推荐指数
2
解决办法
4465
查看次数

临时参数值什么时候超出范围?

可能重复:
临时生活

int LegacyFunction(const char *s) {
    // do something with s, like print it to standard output
    // this function does NOT retain any pointer to s after it returns.
    return strlen(s);
}

std::string ModernFunction() {
    // do something that returns a string
    return "Hello";
}

LegacyFunction(ModernFunction().c_str());
Run Code Online (Sandbox Code Playgroud)

可以轻松地重写上面的示例以使用智能指针而不是字符串; 我多次遇到过这两种情况.无论如何,上面的例子将在ModernFunction中构造一个STL字符串,返回它,然后获取一个指向字符串对象内部的C风格字符串的指针,然后将该指针传递给遗留函数.

  1. 在返回ModernFunction之后,存在一个临时字符串对象.什么时候超出范围?
  2. 编译器是否可以调用c_str(),破坏此临时字符串对象,然后将悬空指针传递给LegacyFunction?(请记住,字符串对象正在管理c_str()返回值指向...的内存.
  3. 如果上面的代码不安全,为什么它不安全,并且有一种更好,同样简洁的方法来编写它而不是在进行函数调用时添加一个临时变量?如果它安全,为什么?

c++

19
推荐指数
2
解决办法
2955
查看次数

包含带有"git log"的子模块提交消息

假设我的存储库中有两个版本...每个版本都标记如下:

  • TAG1
  • TAG2

现在假设提交更新了子模块引用以指向Tag1和Tag2之间的新子模块提交.我运行以下命令,得到这个:

# show commits between these two tags
git log Tag1..Tag2


commit be3d0357b93322f472e8f03285cb3e1e0592eabd
Author: James Johnston <snip>
Date:   Wed Jan 25 19:42:56 2012 +0000

    Updated submodule references.
Run Code Online (Sandbox Code Playgroud)

在这种情况下,唯一的变化是子模块的更新.如何让子模块提交与父存储库提交交错?

具体来说,在此示例中,假设父存储库指向子模块中的SubTag5标记.子模块后面的两个提交是SubTag6标记.显示的提交更新了子模块指针,指向SubTag6而不是SubTag5.git log除了已经打印的提交之外,我想要做的是打印两个子模块提交,以便将SubTag5的子模块带到SubTag6.

git

17
推荐指数
2
解决办法
8153
查看次数

混合来自不同编译器的C++代码

假设我有两个项目要联系在一起:

  • 用Visual C++编译为DLL文件的C++库.
  • 使用C++ Builder编译的C++可执行文件,它使用库中的类.

我意识到没有标准的C++ ABI,任何将这两个C++项目直接链接在一起的尝试都会失败.什么是创建兼容性层的好的,自动化的方式,允许我完成此任务?

例如,可以想象C++库可以通过C接口暴露自己.然后,可执行文件将包含一些C++类,这些类包装C++库公开的C接口.由于一个标准的ABI的C,它会工作.

唯一的问题是如何自动创建C接口和C++包装类 - 手动维护这不是一个选项.SWIG项目看起来很有希望,但不幸的是,C++并不是他们网站上列出的SWIG的出口之一.有没有办法用SWIG做我想做的事情?或者除了SWIG之外还有其他项目可以帮助我完成这项任务吗?

或者我是以错误的方式来做这件事的?

编辑: 核心C++库旨在跨平台.显然,可执行文件是特定于Windows的.我不想污染核心库,以至于无法在其他平台上编译它.

c c++ windows swig

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

QWebView/Qt WebKit不会打开一些SSL页面; 不允许重定向?

使用Visual C++ 2008 SP1在Windows 7上干净安装Qt SDK 1.1.4; 我正在使用Qt Creator.为什么这段代码没有加载某些网页?

#include <QtGui/QApplication>
#include <QtWebKit/QWebView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWebView b;
    b.load(QUrl("https://gmail.com")); // doesn't work
    //b.load(QUrl("https://accounts.google.com")); // works
    //b.load(QUrl("https://google.com")); // doesn't work
    //b.load(QUrl("https://www.google.com")); // works
    b.show();

    return a.exec();
}
Run Code Online (Sandbox Code Playgroud)

为什么有些网址不起作用,有些网址不起作用?

我认为google.com/www.google.com特别有说服力; google.com通常会重定向到www.google.com.gmail.com正在重定向到accounts.google.com.WebKit不允许安全页面重定向吗?如果是这样,如何解决?

顺便说一下,Qt SDK 1.1.4似乎包含了OpenSSL; 我注意到它出现在C:\ QtSDK\Desktop\Qt\4.7.4\msvc2008\bin\ssleay32.dll.还要注意一些页面似乎有效,而不是其他页面.

编辑: 另外两个网址:

b.load(QUrl("https://support.motionview3d.com/help/_media/images/directory.png")); // doesn't work
b.load(QUrl("https://mail.google.com")); // works
Run Code Online (Sandbox Code Playgroud)

同样,这两种方法在其他Web浏览器中都可以正常工作.

c++ ssl qt qt4 qtwebkit

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

安全地将只读数据传递给新线程

假设我有一个程序初始化一个全局变量供线程使用,如下所示:

int ThreadParameter;

// this function runs from the main thread
void SomeFunction() {
    ThreadParameter = 5;

    StartThread(); // some function to start a thread
    // at this point, ThreadParameter is NEVER modified.
}

// this function is run in a background worker thread created by StartThread();
void WorkerThread() {
    PrintValue(ThreadParameter); // we expect this to print "5"
}
Run Code Online (Sandbox Code Playgroud)

这些问题应适用于可能遇到的任何通用处理器体系结构.我希望解决方案是可移植的 - 不是特定于具有更强内存保证的架构,如x86.

  1. 一般问题:尽管非常普遍,但这在所有处理器架构中是否真的安全?如果不安全,如何安全?
  2. 全局变量不是volatile; 是否可能会在StartThread()通话结束后重新订购并留下我的话?如何解决这个问题?
  3. 假设计算机有两个具有自己的缓存的处理器.主线程在第一个处理器上运行,工作线程在第二个处理器上运行 假设在ThreadParameter程序开始运行之前,包含的内存块已被分页到每个处理器的缓存中SomeFunction(). SomeFunction()5ThreadParameter …

c c++ multithreading thread-safety

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

免费的Windows Subversion GUI,不使用shell扩展

我需要一个满足以下要求的Subversion用户界面:

  • 在Windows上运行的用户界面
  • 不需要使用shell扩展(如果包含一个,它应该是可选的)
  • 积极维护(即过去一年内新的,定期发布)
  • 自由

令人惊讶的是,我很难找到这样的东西!我希望它能用于偶尔的Subversion存储库 - 我不会每天都使用它.出于这个原因,像TortoiseSVN这样的选项并不是真正需要的,因为它们会使我的Windows资源管理器外壳变得混乱和变慢.(我已经为Git和其他一百万个应用程序提供了shell扩展,我需要的最后一件事就是我将很少使用的源控件包的另一个shell扩展.)

Git的可比项目是Git Extensions.二进制文件是为Windows提供的,它是GPL,最后一个版本是在过去30天内,而shell扩展是可选的:它是一个独立的GUI.我很惊讶我没有为SVN找到这样的东西......

svn

10
推荐指数
2
解决办法
8505
查看次数

什么是REBASE.EXE的替代品?

我需要重新设置我用我的程序安装的DLL文件组,因为它是一个32位程序,地址空间现在太碎片了.还有一个问题是,由于基地址与某些DLL冲突,整个DLL在冷启动时被请求分页到RAM中,因此加载器可以对它们进行重新绑定.有些DLL是我们编译过的; 其他人来自第三方.

我想要做的是有一个工具rebase一组给定的DLL,以便DLL组占用一个连续的内存块.然后,在编译安装程序之前运行此工具,并将重新定义的DLL安装在应用程序的专用目录中.

据我所知,Windows SDK附带的REBASE.EXE工具确实做到了这一点.给它一些DLL,然后重新定义它们.

不幸的是... Windows 8 Consumer Preview的Windows软件开发工具包(SDK)说:

工具许多已过时或已弃用的工具已从Windows SDK中删除.已删除以下工具:

<snip> ReBase.exe

现在怎么办?我不想开始使用明显过时的工具,并且将在下一版本的Windows中消失.假设我正在读这个,那么使用ReBase.exe有什么替代品?我想限制自己使用Windows SDK和/或Visual Studio附带的工具,而不是引入第三方工具和/或编写我自己的rebase代码.

或者,我是否以错误的方式处理整个问题?

windows dll winapi rebase visual-c++

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

标签 统计

c++ ×6

windows ×4

c ×3

qt ×2

qt4 ×2

winapi ×2

bash ×1

cygwin ×1

dll ×1

fonts ×1

git ×1

multithreading ×1

qmake ×1

qt-creator ×1

qtwebkit ×1

rebase ×1

ssl ×1

svn ×1

swig ×1

thread-safety ×1

visual-c++ ×1