2017-02-07 2 views
1

J'essaie de comprendre, quelle est la limitation de la taille de la pile, lorsque les appels MATLAB fonctionnent dans DLL.
Existe-t-il un moyen de configurer la limite?Quelle est la limite de pile lorsque les appels MATLAB fonctionnent dans la DLL

J'utilise les fonctions loadlibrary et calllib pour appeler la fonction implémentée en C (dans la bibliothèque Dynamic-Link). J'ai créé un test pour déterminer la limite de la pile. J'utilise MATLAB 2016a (64 bits) et Visual Studio 2010 pour créer la DLL.

Voici mon code source Matlab:

loadlibrary('MyDll','MyDll.h') 

size_in_bytes = 1000000; 

res = calllib('MyDll', 'Test', size_in_bytes); 

if (res == -1) 
    disp(['Stack Overflow... (size = ', num2str(size_in_bytes), ')']); 
else 
    disp(['Successful stack allocation... (size = ', num2str(size_in_bytes), ')']); 
end 

unloadlibrary MyDll 

Voici mon code source C:

MyDll.h

// MyDll.h : DLL interface. 

#ifndef MY_DLL_H 
#define MY_DLL_H 

#ifdef MY_DLL_EXPORTS 
    #define MY_DLL_API __declspec(dllexport) 
#else 
    #define MY_DLL_API __declspec(dllimport) 
#endif 

extern MY_DLL_API int Test(int size); 

#endif 

MYDLL.C

// MyDll.c 

#include "MyDll.h" 

#include <windows.h> 
#include <stdio.h> 
#include <string.h> 
#include <malloc.h> 


//Allocate <size> bytes in stack using _alloca(size). 
//Return 0 if OK. 
//Return (-1) in case of stack overflow. 
int Test(int size) 
{ 
    //Not allocated on the stack... 
    static wchar_t errorMsg[100]; 
    static wchar_t okMsg[100]; 

    int errcode = 0; 
    void *pData = NULL; 

    //Prepare messages from advance. 
    swprintf_s(errorMsg, 100, L"Stack Overflow (size = %d)", size); 
    swprintf_s(okMsg, 100, L"Successful stack allocation (size = %d)", size); 

    __try 
    { 
     pData = _alloca(size); 
    } 
    // If an exception occurred with the _alloca function 
    __except (GetExceptionCode() == STATUS_STACK_OVERFLOW) 
    { 
     MessageBox(NULL, errorMsg, TEXT("Error"), MB_OK | MB_ICONERROR); 

     // If the stack overflows, use this function to restore. 
     errcode = _resetstkoflw(); 
     if (errcode) 
     { 
      MessageBox(NULL, TEXT("Could not reset the stack!"), TEXT("Error"), MB_OK | MB_ICONERROR); 
      _exit(1); 
     } 

     pData = NULL; 
    }; 

    if (pData != NULL) 
    { 
     //Fill allocated buffer with zeros 
     memset(pData, 0, size); 

     MessageBox(NULL, okMsg, TEXT("OK"), MB_OK); 

     return 0; 
    } 

    return -1; 
} 

Le bloc __try et __except est pris de l'exemple Microsoft:
https://msdn.microsoft.com/en-us/library/wb1s57t5.aspx

DLL drapeaux du compilateur:
/Zi /nologo /W4 /WX- /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_USRDLL" /D "MY_DLL_EXPORTS" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MTd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fp"x64\Debug\MyDll.pch" /Fa"x64\Debug\" /Fo"x64\Debug\" /Fd"x64\Debug\vc100.pdb" /Gd /errorReport:queue

drapeaux DLL Linker:
/OUT:"x64\Debug\MyDll.dll" /INCREMENTAL:NO /NOLOGO /DLL "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /MANIFEST /ManifestFile:"x64\Debug\MyDll.dll.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"c:\Tmp\MyDll\x64\Debug\MyDll.pdb" /SUBSYSTEM:CONSOLE /PGD:"c:\Tmp\MyDll\x64\Debug\MyDll.pgd" /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X64 /ERRORREPORT:QUEUE


J'ai exécuté le code MATLAB en utilisant différentes valeurs de size_in_bytes:
size_in_bytes = 1000000: Passez!
size_in_bytes = 10000000: Passez!
size_in_bytes = 50000000: Passez!
size_in_bytes = 60000000: Passez!
size_in_bytes = 70000000: dépassement de pile!

On dirait que la limite dans mon système est d'environ 64 Mo (mais je ne sais pas si ce nombre est vrai pour tous les systèmes).


I a essayé de modifier la taille de la pile de Matlab.exe utilisant editbin outil. J'ai essayé la commande suivante (par exemple):
editbin /STACK:250000000 "c:\Program Files\MATLAB\R2016a\bin\matlab.exe".

Cette option définit la taille de la pile en octets et prend les arguments en notation décimale ou en langage C. L'option/STACK s'applique uniquement à un fichier exécutable.

Cela ne semble pas affecter ...

+0

La taille de la pile est définie au moment de l'exécution. Vous devez donc vérifier la taille de la pile allouée par votre os. En passant, vous me donnez une crise cardiaque avec '__try' en C. – Stargateur

+0

Alors, comment puis-je définir la taille dans Windows 10? – Rotem

Répondre

0

Il semble que sur les fenêtres, la taille de la pile est définie au moment de la compilation. Vous pouvez donc utiliser l'option /F ou le binaire EDITBIN.

+0

Voulez-vous dire utiliser 'editbin' pour changer' Matlab.exe'? Comme ceci: 'editbin/pile: 250000000" c: \ Program Files \ MATLAB \ R2016a \ bin \ matlab.exe "'. Il semble n'avoir aucun effet ... – Rotem

+1

Votre réponse semble être fausse. Pouvez-vous s'il vous plaît le supprimer? – Rotem