MATLAB在DLL中调用函数时的堆栈限制是多少 [英] What is the stack limit when MATLAB calls function in DLL

查看:188
本文介绍了MATLAB在DLL中调用函数时的堆栈限制是多少的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当MATLAB在DLL中调用函数时,我试图弄清楚堆栈大小的限制是什么.
有没有配置限制的方法?

I am trying to figure out, what is the stack size limitation, when MATLAB calls function in DLL.
Is there a way to configure the limit?

我正在使用loadlibrarycalllib函数来调用用C实现的函数(在动态链接库中).

I am using loadlibrary, and calllib functions to call function implemented in C (in Dynamic-link library).

我创建了一个测试来确定堆栈限制.

I created a test to figure out the stack limit.

我正在使用MATLAB 2016a(64位)和Visual Studio 2010来构建DLL.

I am using MATLAB 2016a (64 bits), and Visual Studio 2010 for building the DLL.

这是我的MATLAB源代码:

Here is my MATLAB source code:

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

这是我的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;
}

__try__except块取自Microsoft示例:
https://msdn.microsoft.com/en-us/library/wb1s57t5. aspx

The __try and __except block is taken from Microsoft example:
https://msdn.microsoft.com/en-us/library/wb1s57t5.aspx

DLL编译器标志:
/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

DLL Compiler flags:
/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

DLL链接器标志:
/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

DLL Linker flags:
/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

我使用不同的size_in_bytes值执行了MATLAB代码:
size_in_bytes = 1000000:通过!
size_in_bytes = 10000000:通过!
size_in_bytes = 50000000:通过!
size_in_bytes = 60000000:通过!
size_in_bytes = 70000000:堆栈溢出!

I executed the MATLAB code using different values of size_in_bytes:
size_in_bytes = 1000000: Pass!
size_in_bytes = 10000000: Pass!
size_in_bytes = 50000000: Pass!
size_in_bytes = 60000000: Pass!
size_in_bytes = 70000000: Stack Overflow!

看起来我的系统限制约为64MByte(但我不知道此数字是否对所有系统都适用).

Looks like the limit in my system is about 64MByte (but I don't know if this number is true for all systems).

我尝试使用 editbin Matlab.exe的堆栈大小>工具.
我尝试了以下命令(例如):
editbin /STACK:250000000 "c:\Program Files\MATLAB\R2016a\bin\matlab.exe".

I tried to modify stack size of Matlab.exe using editbin tool.
I tried the following command (for example):
editbin /STACK:250000000 "c:\Program Files\MATLAB\R2016a\bin\matlab.exe".

此选项以字节为单位设置堆栈的大小,并以十进制或C语言表示法接受参数./STACK选项仅适用于可执行文件.

This option sets the size of the stack in bytes and takes arguments in decimal or C-language notation. The /STACK option applies only to an executable file.

似乎没有影响...

推荐答案

似乎在Windows上,堆栈大小是在编译时设置的.因此,您可以使用选项/F 或二进制文件 EDITBIN .

Seems that on windows the size of the stack is set at compile time. So you can use option /F or the binary EDITBIN.

例如,您可以编辑以下文件:

For example, you could to edit the following file:

EDITBIN /STACK:134217728 "C:\Program Files\MATLAB\R2016a\bin\win64\MATLAB.exe"

这会将堆栈大小设置为128 MB(128 x 1024 x 1024字节= 134217728字节).

This would set the stack size to 128 MB (128 x 1024 x 1024 Bytes = 134217728 Bytes).

注意:请注意,编辑C:\Program Files\MATLAB\R2016a\bin\matlab.exe无效.

Note: be aware that editing the C:\Program Files\MATLAB\R2016a\bin\matlab.exe will have no effect.

这篇关于MATLAB在DLL中调用函数时的堆栈限制是多少的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆