DLL的发布 - 构建表现出意外

时间:2015-07-21 11:35:06

标签: c++ dll compiler-optimization jna

我有一个VS2013项目来构建一个DLL,我使用JNA从Java调用。一切正常,只要我使用调试配置 - 但是当使用任何优化(配置属性 - > C / C ++ - >优化 - >除了“禁用(/ Od)”之外的其他所有内容)时,行为就变成了某种东西意外。我想理解为什么会这样 - 在这种情况下,我是否依赖于未定义的行为?

我对调用createObject()两次的期望是:第一次调用应该返回true(因为实例未初始化并且将被初始化),第二次调用应该返回false(因为实例应该返回已初始化)。但是,如果我使用Release-Build(或在Debug-Build中激活Optimizations)createObject()每次连续调用都会返回true

我的C ++代码:

#include <windows.h> 
#include <memory>

#define DLL_EXPORT

#ifdef DLL_EXPORT
#    define CALLCONV extern "C" __declspec(dllexport)
#else
#    define CALLCONV extern "C" __declspec(dllimport)
#endif

class MyType{

};

std::unique_ptr<MyType> instance = nullptr;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){
  switch (fdwReason){
  case DLL_PROCESS_ATTACH:
    break;
  case DLL_PROCESS_DETACH:
    break;
  case DLL_THREAD_ATTACH:
    break;
  case DLL_THREAD_DETACH:
    break;
  default:
    break;
  }
  return TRUE;
}

CALLCONV bool createObject(){
  bool retVal = true;
  if (instance == nullptr){
    instance = std::unique_ptr<MyType>(new MyType());
  }else{
    retVal = false;
  }
  return retVal;
}

仅供参考,我调用JNA代码(但我想,如果我从本机代码调用它,同样的问题就会存在):

import com.sun.jna.Library;
import com.sun.jna.Native;

public class main {
  public interface TestLibrary extends Library {
    TestLibrary INSTANCE = (TestLibrary)Native.loadLibrary("Test", TestLibrary.class);
    boolean createObject();
  }

  public static void main(String[] args) {
    try {
      System.out.println(TestLibrary.INSTANCE.createObject());
      System.out.println(TestLibrary.INSTANCE.createObject());
    } catch (UnsatisfiedLinkError e) {
      System.err.println("Native code library failed to load.\n" + e);
      System.exit(1);
    }
  }
}

1 个答案:

答案 0 :(得分:1)

bool的大小取决于实现。 JNA假定从本机int默认转换为boolean。您应确保您的本机代码返回具有明确定义大小的内容,以便JNA可以可靠地执行转换。

JNA要求所有内容都有明确定义的大小,以便正确执行Java到本机转换。