2015-07-21 32 views
-1

我有一個VS2013項目建立一個DLL,我使用JNA從Java調用。只要我使用調試配置 - 但是當使用任何優化(配置屬性 - > C/C++ - >優化 - >除了「Disabled(/ Od)」之外的其他一切),所有行爲都會出現預期,這種行爲會變得意想不到。我想明白爲什麼會這樣 - 在這種情況下,我是否依賴未定義的行爲?DLL的發佈 - 建立行爲意外

我上調用createObject()期望兩次:第一次調用應該返回true(因爲實例初始化,將被初始化),第二次調用應返回false(因爲實例應該是已經初始化)。但是,如果我使用Release-Build(或者在Debug-Build中激活優化),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

您似乎在'instance = std :: unique_ptr (new MyType())後面缺少'retVal = true;'語句;'雖然沒有解釋問題。 – Bathsheba

+0

您的代碼無法正常返回「true」,因爲'retVal'永遠不會設置爲'true'。有沒有更多的代碼你沒有顯示?或者它是完整的例子? –

+0

你可以測試一下,如果你添加一些數據成員到'MyType',那麼它不是空的?另外,嘗試將if(instance == nullptr)'改爲'if(instance.get()== nullptr)'。 –

回答

1

布爾的大小取決於實現。 JNA默認從本地int轉換爲布爾值。您應該確保您的本機代碼正在返回具有明確定義大小的內容,以便JNA可以可靠地進行轉換。

JNA需要定義明確的大小以便正確執行Java到本地翻譯。